test: iop.h File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# iop.h File Reference

`#include "ntos.h"`
`#include "ntdddisk.h"`
`#include "ntddscsi.h"`
`#include "mountmgr.h"`
`#include "ntiodump.h"`
`#include "ntiolog.h"`
`#include "ntiologc.h"`
`#include "ntseapi.h"`
`#include "zwapi.h"`
`#include "stdio.h"`
`#include "stdlib.h"`
`#include "string.h"`
`#include "fsrtl.h"`
`#include "pnpiop.h"`
`#include "ioverifier.h"`
`#include "safeboot.h"`

Go to the source code of this file.

## Classes

struct | _ERROR_LOG_ENTRY
struct | _IOP_HARD_ERROR_QUEUE
struct | _IOP_HARD_ERROR_PACKET
struct | _IOP_APC_HARD_ERROR_PACKET
struct | _IO_WORKITEM
struct | _DUMMY_FILE_OBJECT
struct | _OPEN_PACKET
struct | _LOAD_PACKET
struct | _LINK_TRACKING_PACKET
struct | _REINIT_PACKET
struct | _SHUTDOWN_PACKET
struct | _NOTIFICATION_PACKET
struct | _IOP_MINI_COMPLETION_PACKET
struct | _MINIPORT_NODE
struct | _DUMP_CONTROL_BLOCK

## Defines

#define | IOP_ABORT 1
#define | IOP_MAXIMUM_LOG_ALLOCATION PAGE_SIZE
#define | IOP_MAXIMUM_OUTSTANDING_HARD_ERRORS 25
#define | OPEN_PACKET_PATTERN 0xbeaa0251
#define | IO_TYPE_DCB 0xff
#define | DCB_DUMP_ENABLED 0x01
#define | DCB_SUMMARY_ENABLED 0x02
#define | DCB_AUTO_REBOOT 0x04
#define | DCB_DUMP_HEADER_ENABLED 0x10
#define | DCB_SUMMARY_DUMP_ENABLED 0x20
#define | DCB_TRIAGE_DUMP_ENABLED 0x40
#define | DCB_TRIAGE_DUMP_ACT_UPON_ENABLED 0x80
#define | IOP_FIXED_SIZE_MDL_PFNS 0x17
#define | IopAcquireFastLock(FileObject) ( InterlockedExchange( &FileObject->Busy, (ULONG) TRUE ) == FALSE )
#define | IopAcquireCancelSpinLockAtDpcLevel() ExAcquireSpinLockAtDpcLevel (&IopCancelSpinLock)
#define | IopReleaseCancelSpinLockFromDpcLevel() ExReleaseSpinLockFromDpcLevel (&IopCancelSpinLock)
#define | IopAllocateIrp(StackSize, ChargeQuota) IoAllocateIrp((StackSize), (ChargeQuota))
#define | IsIoVerifierOn() IopVerifierOn
#define | IopDequeueThreadIrp(Irp)
#define | IopApcRoutinePresent(ApcRoutine) ARGUMENT_PRESENT(ApcRoutine)
#define | IopInitializeIrp(Irp, PacketSize, StackSize)
#define | IopQueueThreadIrp(Irp)
#define | IopReleaseFileObjectLock(FileObject)

## Typedefs

typedef enum _TRANSFER_TYPE | TRANSFER_TYPE
typedef enum _TRANSFER_TYPE * | PTRANSFER_TYPE
typedef _ERROR_LOG_ENTRY | ERROR_LOG_ENTRY
typedef _ERROR_LOG_ENTRY * | PERROR_LOG_ENTRY
typedef _IOP_HARD_ERROR_QUEUE | IOP_HARD_ERROR_QUEUE
typedef _IOP_HARD_ERROR_QUEUE * | PIOP_HARD_ERROR_QUEUE
typedef _IOP_HARD_ERROR_PACKET | IOP_HARD_ERROR_PACKET
typedef _IOP_HARD_ERROR_PACKET * | PIOP_HARD_ERROR_PACKET
typedef _IOP_APC_HARD_ERROR_PACKET | IOP_APC_HARD_ERROR_PACKET
typedef _IOP_APC_HARD_ERROR_PACKET * | PIOP_APC_HARD_ERROR_PACKET
typedef IN PIRP | Irp
typedef IN CCHAR | PriorityBoost
typedef VOID(* | PIO_FREE_IRP )(IN struct _IRP *Irp)
typedef PIRP(* | PIO_ALLOCATE_IRP )(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
typedef _IO_WORKITEM | IO_WORKITEM
typedef _DUMMY_FILE_OBJECT | DUMMY_FILE_OBJECT
typedef _DUMMY_FILE_OBJECT * | PDUMMY_FILE_OBJECT
typedef _OPEN_PACKET | OPEN_PACKET
typedef _OPEN_PACKET * | POPEN_PACKET
typedef _LOAD_PACKET | LOAD_PACKET
typedef _LOAD_PACKET * | PLOAD_PACKET
typedef _LINK_TRACKING_PACKET | LINK_TRACKING_PACKET
typedef _LINK_TRACKING_PACKET * | PLINK_TRACKING_PACKET
typedef _REINIT_PACKET | REINIT_PACKET
typedef _REINIT_PACKET * | PREINIT_PACKET
typedef _SHUTDOWN_PACKET | SHUTDOWN_PACKET
typedef _SHUTDOWN_PACKET * | PSHUTDOWN_PACKET
typedef _NOTIFICATION_PACKET | NOTIFICATION_PACKET
typedef _NOTIFICATION_PACKET * | PNOTIFICATION_PACKET
typedef enum _COMPLETION_PACKET_TYPE | COMPLETION_PACKET_TYPE
typedef enum _COMPLETION_PACKET_TYPE * | PCOMPLETION_PACKET_TYPE
typedef _IOP_MINI_COMPLETION_PACKET | IOP_MINI_COMPLETION_PACKET
typedef _IOP_MINI_COMPLETION_PACKET * | PIOP_MINI_COMPLETION_PACKET
typedef _MINIPORT_NODE | MINIPORT_NODE
typedef _MINIPORT_NODE * | PMINIPORT_NODE
typedef _DUMP_CONTROL_BLOCK | DUMP_CONTROL_BLOCK
typedef _DUMP_CONTROL_BLOCK * | PDUMP_CONTROL_BLOCK

## Enumerations

enum | _TRANSFER_TYPE { ReadTransfer, WriteTransfer, OtherTransfer }
enum | _COMPLETION_PACKET_TYPE { IopCompletionPacketIrp, IopCompletionPacketMini, IopCompletionPacketQuota }

## Functions

typedef | NTSTATUS (FASTCALL *PIO_CALL_DRIVER)(IN PDEVICE_OBJECT DeviceObject
typedef | VOID (FASTCALL *PIO_COMPLETE_REQUEST)(IN PIRP Irp
VOID | IopAbortRequest (IN PKAPC Apc)
NTSTATUS | IopAcquireFileObjectLock (IN PFILE_OBJECT FileObject, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN Alertable, OUT PBOOLEAN Interrupted)
VOID | IopAllocateIrpCleanup (IN PFILE_OBJECT FileObject, IN PKEVENT EventObject OPTIONAL)
PIRP | IopAllocateIrpMustSucceed (IN CCHAR StackSize)
VOID | IopApcHardError (IN PVOID StartContext)
VOID | IopCancelAlertedRequest (IN PKEVENT Event, IN PIRP Irp)
VOID | IopCheckBackupRestorePrivilege (IN PACCESS_STATE AccessState, IN OUT PULONG CreateOptions, IN KPROCESSOR_MODE PreviousMode, IN ULONG Disposition)
NTSTATUS | IopCheckGetQuotaBufferValidity (IN PFILE_GET_QUOTA_INFORMATION QuotaBuffer, IN ULONG QuotaLength, OUT PULONG_PTR ErrorOffset)
VOID | IopCloseFile (IN PEPROCESS Process OPTIONAL, IN PVOID Object, IN ULONG GrantedAccess, IN ULONG ProcessHandleCount, IN ULONG SystemHandleCount)
VOID | IopCompleteUnloadOrDelete (IN PDEVICE_OBJECT DeviceObject, IN KIRQL Irql)
VOID | IopCompletePageWrite (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
VOID | IopCompleteRequest (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
VOID | IopConnectLinkTrackingPort (IN PVOID Parameter)
VOID | IopCreateVpb (IN PDEVICE_OBJECT DeviceObject)
VOID | IopDeallocateApc (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
VOID | IopDecrementDeviceObjectRef (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AlwaysUnload)
VOID | IopDeleteDriver (IN PVOID Object)
VOID | IopDeleteDevice (IN PVOID Object)
VOID | IopDeleteFile (IN PVOID Object)
VOID | IopDeleteIoCompletion (IN PVOID Object)
VOID | IopDisassociateThreadIrp (VOID)
BOOLEAN | IopDmaDispatch (IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
VOID | IopDropIrp (IN PIRP Irp, IN PFILE_OBJECT FileObject)
LONG | IopExceptionFilter (IN PEXCEPTION_POINTERS ExceptionPointers, OUT PNTSTATUS ExceptionCode)
VOID | IopExceptionCleanup (IN PFILE_OBJECT FileObject, IN PIRP Irp, IN PKEVENT EventObject OPTIONAL, IN PKEVENT KernelEvent OPTIONAL)
VOID | IopErrorLogThread (IN PVOID StartContext)
VOID | IopFreeIrpAndMdls (IN PIRP Irp)
PDEVICE_OBJECT | IopGetDeviceAttachmentBase (IN PDEVICE_OBJECT DeviceObject)
PDEVICE_OBJECT | IopGetDeviceAttachmentBaseRef (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS | IopGetDriverNameFromKeyNode (IN HANDLE KeyHandle, OUT PUNICODE_STRING DriverName)
ULONG | IopGetDumpControlBlockCheck (IN PDUMP_CONTROL_BLOCK Dcb)
NTSTATUS | IopGetFileName (IN PFILE_OBJECT FileObject, IN ULONG Length, OUT PVOID FileInformation, OUT PULONG ReturnedLength)
BOOLEAN | IopGetMountFlag (IN PDEVICE_OBJECT DeviceObject)
NTSTATUS | IopGetRegistryKeyInformation (IN HANDLE KeyHandle, OUT PKEY_FULL_INFORMATION *Information)
NTSTATUS | IopGetRegistryValue (IN HANDLE KeyHandle, IN PWSTR ValueName, OUT PKEY_VALUE_FULL_INFORMATION *Information)
NTSTATUS | IopGetRegistryValues (IN HANDLE KeyHandle, IN PKEY_VALUE_FULL_INFORMATION *ValueList)
NTSTATUS | IopGetSetObjectId (IN PFILE_OBJECT FileObject, IN OUT PVOID Buffer, IN ULONG Length, IN ULONG OperationFlags)
NTSTATUS | IopGetSetSecurityObject (IN PVOID Object, IN SECURITY_OPERATION_CODE OperationCode, IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG CapturedLength, IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
NTSTATUS | IopGetVolumeId (IN PFILE_OBJECT FileObject, IN OUT PLINK_TRACKING_INFORMATION ObjectId, IN ULONG Length)
VOID | IopHardErrorThread (PVOID StartContext)
VOID | IopInitializeResourceMap (PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID | IopInsertRemoveDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Insert)
NTSTATUS | IopInvalidDeviceRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
NTSTATUS | IopInvalidateVolumesForDevice (IN PDEVICE_OBJECT DeviceObject)
BOOLEAN | IopIsSameMachine (IN PFILE_OBJECT SourceFile, IN HANDLE TargetFile)
NTSTATUS | IopLoadDriver (IN HANDLE KeyHandle, IN BOOLEAN CheckForSafeBoot)
VOID | IopLoadFileSystemDriver (IN PDEVICE_OBJECT DeviceObject)
VOID | IopLoadUnloadDriver (IN PVOID Parameter)
NTSTATUS | IopLookupBusStringFromID (IN HANDLE KeyHandle, IN INTERFACE_TYPE InterfaceType, OUT PWCHAR Buffer, IN ULONG Length, OUT PULONG BusFlags OPTIONAL)
NTSTATUS | IopMountVolume (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount, IN BOOLEAN DeviceLockAlreadyHeld, IN BOOLEAN Alertable)
BOOLEAN | IopNotifyPnpWhenChainDereferenced (IN PDEVICE_OBJECT *PhysicalDeviceObjects, IN ULONG DeviceObjectCount, IN BOOLEAN Query, OUT PDEVICE_OBJECT *VetoingDevice)
NTSTATUS | IopOpenLinkOrRenameTarget (OUT PHANDLE TargetHandle, IN PIRP Irp, IN PVOID RenameBuffer, IN PFILE_OBJECT FileObject)
NTSTATUS | IopOpenRegistryKey (OUT PHANDLE Handle, IN HANDLE BaseHandle OPTIONAL, IN PUNICODE_STRING KeyName, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Create)
NTSTATUS | IopParseDevice (IN PVOID ParseObject, IN PVOID ObjectType, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
NTSTATUS | IopParseFile (IN PVOID ParseObject, IN PVOID ObjectType, IN PACCESS_STATE AccessState, IN KPROCESSOR_MODE AccessMode, IN ULONG Attributes, IN OUT PUNICODE_STRING CompleteName, IN OUT PUNICODE_STRING RemainingName, IN OUT PVOID Context OPTIONAL, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, OUT PVOID *Object)
BOOLEAN | IopProtectSystemPartition (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS | IopQueryName (IN PVOID Object, IN BOOLEAN HasObjectName, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
NTSTATUS | IopQueryXxxInformation (IN PFILE_OBJECT FileObject, IN ULONG InformationClass, IN ULONG Length, OUT PVOID Information, OUT PULONG ReturnedLength, IN BOOLEAN FileInformation)
VOID | IopQueueWorkRequest (IN PIRP Irp)
VOID | IopRaiseHardError (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID | IopRaiseInformationalHardError (IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
VOID | IopReadyDeviceObjects (IN PDRIVER_OBJECT DriverObject)
NTSTATUS | IopSetEaOrQuotaInformationFile (IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID Buffer, IN ULONG Length, IN BOOLEAN SetEa)
NTSTATUS | IopSetRemoteLink (IN PFILE_OBJECT FileObject, IN PFILE_OBJECT DestinationFileObject OPTIONAL, IN PFILE_TRACKING_INFORMATION FileInformation OPTIONAL)
VOID | IopStartApcHardError (IN PVOID StartContext)
NTSTATUS | IopSynchronousApiServiceTail (IN NTSTATUS ReturnedStatus, IN PKEVENT Event, IN PIRP Irp, IN KPROCESSOR_MODE RequestorMode, IN PIO_STATUS_BLOCK LocalIoStatus, OUT PIO_STATUS_BLOCK IoStatusBlock)
NTSTATUS | IopSynchronousServiceTail (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PFILE_OBJECT FileObject, IN BOOLEAN DeferredIoCompletion, IN KPROCESSOR_MODE RequestorMode, IN BOOLEAN SynchronousIo, IN TRANSFER_TYPE TransferType)
VOID | IopTimerDispatch (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
NTSTATUS | IopTrackLink (IN PFILE_OBJECT FileObject, IN OUT PIO_STATUS_BLOCK IoStatusBlock, IN PFILE_TRACKING_INFORMATION FileInformation, IN ULONG Length, IN PKEVENT Event, IN KPROCESSOR_MODE RequestorMode)
VOID | IopUserCompletion (IN PKAPC Apc, IN PKNORMAL_ROUTINE *NormalRoutine, IN PVOID *NormalContext, IN PVOID *SystemArgument1, IN PVOID *SystemArgument2)
NTSTATUS | IopXxxControlFile (IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN BOOLEAN DeviceIoControl)
NTSTATUS | IopReportResourceUsage (IN PUNICODE_STRING DriverClassName OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PCM_RESOURCE_LIST DriverList OPTIONAL, IN ULONG DriverListSize OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PCM_RESOURCE_LIST DeviceList OPTIONAL, IN ULONG DeviceListSize OPTIONAL, IN BOOLEAN OverrideConflict, OUT PBOOLEAN ConflictDetected)
NTSTATUS | IopAddRemoteBootValuesToRegistry (PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS | IopStartNetworkForRemoteBoot (PLOADER_PARAMETER_BLOCK LoaderBlock)
NTSTATUS | IopStartTcpIpForRemoteBoot (PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN | IopIsRemoteBootCard (IN PDEVICE_NODE DeviceNode, IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PWCHAR HwIds)
NTSTATUS | IopSetupRemoteBootCard (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN HANDLE UniqueIdHandle, IN PUNICODE_STRING UnicodeDeviceInstance)
BOOLEAN | IopSafebootDriverLoad (PUNICODE_STRING DriverId)
PSECURITY_DESCRIPTOR | IopCreateDefaultDeviceSecurityDescriptor (IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN DeviceHasName, IN PUCHAR Buffer, OUT PACL *AllocatedAcl, OUT PSECURITY_INFORMATION SecurityInformation OPTIONAL)
VOID | IopDoNameTransmogrify (IN PIRP Irp, IN PFILE_OBJECT FileObject, IN PREPARSE_DATA_BUFFER ReparseBuffer)
NTSTATUS | IopQueryDeviceCapabilities (IN PDEVICE_NODE DeviceNode, OUT PDEVICE_CAPABILITIES Capabilities)
NTSTATUS | IopLogErrorEvent (IN ULONG SequenceNumber, IN ULONG UniqueErrorValue, IN NTSTATUS FinalStatus, IN NTSTATUS SpecificIOStatus, IN ULONG LengthOfInsert1, IN PWCHAR Insert1, IN ULONG LengthOfInsert2, IN PWCHAR Insert2)
BOOLEAN | IopConfigureCrashDump (IN HANDLE HandlePagingFile)
VOID | IopUpdateOtherOperationCount (VOID)
VOID | IopUpdateReadOperationCount (VOID)
VOID | IopUpdateWriteOperationCount (VOID)
VOID | IopUpdateOtherTransferCount (IN ULONG TransferCount)
VOID | IopUpdateReadTransferCount (IN ULONG TransferCount)
VOID | IopUpdateWriteTransferCount (IN ULONG TransferCount)
NTSTATUS FASTCALL | IopfCallDriver (PDEVICE_OBJECT DeviceObject, PIRP Irp)
VOID FASTCALL | IopfCompleteRequest (IN PIRP Irp, IN CCHAR PriorityBost)
PIRP | IopAllocateIrpPrivate (IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
VOID | IopFreeIrp (IN PIRP Irp)
PVOID | IopAllocateErrorLogEntry (IN PDEVICE_OBJECT deviceObject, IN PDRIVER_OBJECT driverObject, IN UCHAR EntrySize)

## Variables

ULONG | BreakDiskByteOffset
ULONG | BreakPfn
IOP_HARD_ERROR_QUEUE | IopHardError
PIOP_HARD_ERROR_PACKET | IopCurrentHardError
WORK_QUEUE_ITEM | IopErrorLogWorkItem
BOOLEAN | IopErrorLogPortPending
BOOLEAN | IopErrorLogDisabledThisBoot
KSPIN_LOCK | IopErrorLogLock
LIST_ENTRY | IopErrorLogListHead
ULONG | IopErrorLogAllocation
KSPIN_LOCK | IopErrorLogAllocationLock
KSPIN_LOCK | IopCancelSpinLock
KSPIN_LOCK | IopVpbSpinLock
GENERIC_MAPPING | IopFileMapping
GENERIC_MAPPING | IopCompletionMapping
KSPIN_LOCK | IopDatabaseLock
ERESOURCE | IopDatabaseResource
ERESOURCE | IopSecurityResource
LIST_ENTRY | IopDiskFileSystemQueueHead
LIST_ENTRY | IopCdRomFileSystemQueueHead
LIST_ENTRY | IopNetworkFileSystemQueueHead
LIST_ENTRY | IopTapeFileSystemQueueHead
LIST_ENTRY | IopBootDriverReinitializeQueueHead
LIST_ENTRY | IopDriverReinitializeQueueHead
LIST_ENTRY | IopNotifyShutdownQueueHead
LIST_ENTRY | IopNotifyLastChanceShutdownQueueHead
LIST_ENTRY | IopFsNotifyChangeQueueHead
KSPIN_LOCK | IoStatisticsLock
KSEMAPHORE | IopRegistrySemaphore
KSPIN_LOCK | IopTimerLock
LIST_ENTRY | IopTimerQueueHead
KDPC | IopTimerDpc
KTIMER | IopTimer
ULONG | IopTimerCount
ULONG | IopLargeIrpStackLocations
KSPIN_LOCK | IopCompletionLock
POBJECT_TYPE | IoAdapterObjectType
POBJECT_TYPE | IoCompletionObjectType
POBJECT_TYPE | IoControllerObjectType
POBJECT_TYPE | IoDeviceObjectType
POBJECT_TYPE | IoDriverObjectType
POBJECT_TYPE | IoDeviceHandlerObjectType
POBJECT_TYPE | IoFileObjectType
ULONG | IoDeviceHandlerObjectSize
NPAGED_LOOKASIDE_LIST | IopLargeIrpLookasideList
NPAGED_LOOKASIDE_LIST | IopSmallIrpLookasideList
NPAGED_LOOKASIDE_LIST | IopMdlLookasideList
NPAGED_LOOKASIDE_LIST | IopCompletionLookasideList
UCHAR | IopQueryOperationLength []
UCHAR | IopSetOperationLength []
ULONG | IopQueryOperationAccess []
ULONG | IopSetOperationAccess []
UCHAR | IopQuerySetAlignmentRequirement []
UCHAR | IopQueryFsOperationLength []
UCHAR | IopSetFsOperationLength []
ULONG | IopQueryFsOperationAccess []
ULONG | IopSetFsOperationAccess []
UCHAR | IopQuerySetFsAlignmentRequirement []
UNICODE_STRING | IoArcBootDeviceName
UNICODE_STRING | IoArcHalDeviceName
PUCHAR | IoLoaderArcBootDeviceName
PDUMP_CONTROL_BLOCK | IopDumpControlBlock
ULONG | IopDumpControlBlockChecksum
LONG | IopUniqueDeviceObjectNumber
PVOID | IopLinkTrackingServiceObject
PKEVENT | IopLinkTrackingServiceEvent
KEVENT | IopLinkTrackingPortObject
LINK_TRACKING_PACKET | IopLinkTrackingPacket
PVOID | IopLoaderBlock
BOOLEAN | IopRemoteBootCardInitialized
ULONG | IopLookasideIrpFloat
ULONG | IopLookasideIrpLimit
BOOLEAN | IopVerifierOn
PIO_CALL_DRIVER | pIofCallDriver
PIO_COMPLETE_REQUEST | pIofCompleteRequest
PIO_FREE_IRP | pIoFreeIrp
PIO_ALLOCATE_IRP | pIoAllocateIrp
POBJECT_TYPE | ExEventObjectType

## Define Documentation

#define DCB_AUTO_REBOOT 0x04

| Definition at line 444 of file iop.h. Referenced by IopFreeDCB(), IopInitializeDCB(), and IoWriteCrashDump().

#define DCB_DUMP_ENABLED 0x01

| Definition at line 442 of file iop.h. Referenced by IopCalculateRequiredDumpSpace(), IopConfigureCrashDump(), IopReadDumpRegistry(), and IoWriteCrashDump().

#define DCB_DUMP_HEADER_ENABLED 0x10

| Definition at line 445 of file iop.h. Referenced by IopCalculateRequiredDumpSpace(), IopInitializeDumpSpaceAndType(), and IoWriteCrashDump().

#define DCB_SUMMARY_DUMP_ENABLED 0x20

| Definition at line 446 of file iop.h. Referenced by IopCalculateRequiredDumpSpace(), IopInitializeDumpSpaceAndType(), IopReadDumpRegistry(), and IoWriteCrashDump().

#define DCB_SUMMARY_ENABLED 0x02

| Definition at line 443 of file iop.h. Referenced by IopCalculateRequiredDumpSpace(), IopConfigureCrashDump(), IopInitializeDCB(), IopReadDumpRegistry(), and IoWriteCrashDump().

#define DCB_TRIAGE_DUMP_ACT_UPON_ENABLED 0x80

| Definition at line 448 of file iop.h. Referenced by IopReadDumpRegistry(), and TriageActUpon().

#define DCB_TRIAGE_DUMP_ENABLED 0x40

| Definition at line 447 of file iop.h. Referenced by IopCalculateRequiredDumpSpace(), IopInitializeDCB(), IopInitializeDumpSpaceAndType(), IopReadDumpRegistry(), and IoWriteCrashDump().

#define IO_TYPE_DCB 0xff

| Definition at line 440 of file iop.h. Referenced by IopInitializeDCB().

#define IOP_ABORT 1

| Definition at line 65 of file iop.h. Referenced by IopMountVolume(), and IopRaiseHardError().

#define IOP_FIXED_SIZE_MDL_PFNS 0x17

| Definition at line 480 of file iop.h. Referenced by IoAllocateMdl(), and IoInitSystem().

#define IOP_MAXIMUM_LOG_ALLOCATION PAGE_SIZE

| Definition at line 82 of file iop.h. Referenced by IopAllocateErrorLogEntry().

#define IOP_MAXIMUM_OUTSTANDING_HARD_ERRORS 25

| Definition at line 155 of file iop.h. Referenced by IoRaiseInformationalHardError().

#define IopAcquireCancelSpinLockAtDpcLevel | (

)

ExAcquireSpinLockAtDpcLevel (&IopCancelSpinLock)

| Definition at line 598 of file iop.h.

#define IopAcquireFastLock | ( | FileObject |  | ) | ( InterlockedExchange( &FileObject->Busy, (ULONG) TRUE ) == FALSE )

| Definition at line 595 of file iop.h. Referenced by BuildQueryDirectoryIrp(), IopAcquireFileObjectLock(), IopCloseFile(), IopDeleteFile(), IopGetSetSecurityObject(), IopQueryXxxInformation(), IopSetEaOrQuotaInformationFile(), IopXxxControlFile(), IoSetInformation(), NtFlushBuffersFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetEaFile(), NtSetInformationFile(), NtSetVolumeInformationFile(), NtUnlockFile(), NtWriteFile(), and NtWriteFileGather().

#define IopAllocateIrp | ( | StackSize,
|  | ChargeQuota |  | ) | IoAllocateIrp((StackSize), (ChargeQuota))

| Definition at line 604 of file iop.h. Referenced by IopParseDevice(), IopXxxControlFile(), NtReadFile(), NtReadFileScatter(), NtWriteFile(), and NtWriteFileGather().

#define IopApcRoutinePresent | ( | ApcRoutine |  | ) | ARGUMENT_PRESENT(ApcRoutine)

| Definition at line 768 of file iop.h. Referenced by BuildQueryDirectoryIrp(), IopXxxControlFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtReadFile(), NtReadFileScatter(), NtWriteFile(), and NtWriteFileGather().

#define IopDequeueThreadIrp | ( | Irp |  | ) |

Value:

    { \
       RemoveEntryList( &Irp->ThreadListEntry ); \
       InitializeListHead( &Irp->ThreadListEntry ) ; \
       }

Definition at line 758 of file iop.h.

Referenced by IoCancelFileOpen(), IopCloseFile(), IopCompleteRequest(), IopDeleteFile(), and IopParseDevice().

#define IopInitializeIrp | ( | Irp,
|  | PacketSize,
|  | StackSize |  | ) |

Value:

    {          \
        RtlZeroMemory( (Irp), (PacketSize) );                         \
        (Irp)->Type = (CSHORT) IO_TYPE_IRP;                           \
        (Irp)->Size = (USHORT) ((PacketSize));                        \
        (Irp)->StackCount = (CCHAR) ((StackSize));                    \
        (Irp)->CurrentLocation = (CCHAR) ((StackSize) + 1);           \
        (Irp)->ApcEnvironment = KeGetCurrentApcEnvironment();         \
        InitializeListHead (&(Irp)->ThreadListEntry);                 \
        (Irp)->Tail.Overlay.CurrentStackLocation =                    \
            ((PIO_STACK_LOCATION) ((UCHAR *) (Irp) +                  \
                sizeof( IRP ) +                                       \
                ( (StackSize) * sizeof( IO_STACK_LOCATION )))); }

Definition at line 930 of file iop.h.

Referenced by IoMakeAssociatedIrp(), IopAllocateIrpPrivate(), IoReuseIrp(), IovAllocateIrp(), and IovpAllocateIrp1().

#define IopQueueThreadIrp | ( | Irp |  | ) |

Value:

    {                      \
        KIRQL irql;                                         \
        KeRaiseIrql( APC_LEVEL, &irql );                    \
        InsertHeadList( &Irp->Tail.Overlay.Thread->IrpList, \
                        &Irp->ThreadListEntry );            \
        KeLowerIrql( irql );                                \
        }

Definition at line 1103 of file iop.h.

Referenced by IoBuildDeviceIoControlRequest(), IoBuildSynchronousFsdRequest(), IoCancelFileOpen(), IoEnqueueIrp(), IopCloseFile(), IopDeleteFile(), IopFilterResourceRequirementsCall(), IopGetFileName(), IopGetSetSecurityObject(), IopParseDevice(), IopQueryXxxInformation(), IopSynchronousCall(), IopSynchronousServiceTail(), IoQueueThreadIrp(), IoSetInformation(), IovpThrowBogusSynchronousIrp(), NtQueryInformationFile(), and NtSetInformationFile().

#define IopReleaseCancelSpinLockFromDpcLevel | (

)

ExReleaseSpinLockFromDpcLevel (&IopCancelSpinLock)

| Definition at line 601 of file iop.h.

#define IopReleaseFileObjectLock | ( | FileObject |  | ) |

Value:

    {    \
        ULONG Result;                                   \
        Result = InterlockedExchange( &FileObject->Busy, FALSE ); \
        ASSERT(Result != FALSE);                        \
        if (FileObject->Waiters != 0) {                 \
            KeSetEvent( &FileObject->Lock, 0, FALSE );  \
        }                                               \
    }

Definition at line 1157 of file iop.h.

Referenced by IopAllocateIrpCleanup(), IopCloseFile(), IopExceptionCleanup(), IopGetSetSecurityObject(), IopQueryXxxInformation(), IopSynchronousServiceTail(), IopXxxControlFile(), IoSetInformation(), NtQueryInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetInformationFile(), NtWriteFile(), and NtWriteFileGather().

#define IsIoVerifierOn | (

)

IopVerifierOn

| Definition at line 607 of file iop.h.

#define OPEN_PACKET_PATTERN 0xbeaa0251

| Definition at line 196 of file iop.h. Referenced by IoCreateFile(), IoFastQueryNetworkAttributes(), IopParseDevice(), NtDeleteFile(), NtQueryAttributesFile(), and NtQueryFullAttributesFile().

## Typedef Documentation

typedef enum _COMPLETION_PACKET_TYPE COMPLETION_PACKET_TYPE

typedef struct _DUMMY_FILE_OBJECT DUMMY_FILE_OBJECT

typedef struct _DUMP_CONTROL_BLOCK DUMP_CONTROL_BLOCK

| Referenced by IopGetDumpControlBlockCheck().

typedef struct _ERROR_LOG_ENTRY ERROR_LOG_ENTRY

| Referenced by IopErrorLogThread().

typedef struct _IO_WORKITEM IO_WORKITEM

| Referenced by IoAllocateWorkItem().

typedef struct _IOP_APC_HARD_ERROR_PACKET IOP_APC_HARD_ERROR_PACKET

typedef struct _IOP_HARD_ERROR_PACKET IOP_HARD_ERROR_PACKET

| Referenced by IopHardErrorThread(), and IoRaiseInformationalHardError().

typedef struct _IOP_HARD_ERROR_QUEUE IOP_HARD_ERROR_QUEUE

typedef struct _IOP_MINI_COMPLETION_PACKET IOP_MINI_COMPLETION_PACKET

| Referenced by IoInitSystem(), and NtRemoveIoCompletion().

typedef IN PIRP Irp

| Definition at line 130 of file iop.h. Referenced by BuildQueryDirectoryIrp(), CcSetValidData(), CdfsRecFsControl(), FatRecFsControl(), FsRecCleanupClose(), FsRecCreate(), FsRecFsControl(), FsRtlAcknowledgeOplockBreak(), FsRtlBalanceReads(), FsRtlCancelExclusiveIrp(), FsRtlCancelNotify(), FsRtlCancelOplockIIIrp(), FsRtlCancelWaitIrp(), FsRtlCheckLockForReadAccess(), FsRtlCheckLockForWriteAccess(), FsRtlCheckOplock(), FsRtlCompleteLockIrpReal(), FsRtlCompletionRoutinePriv(), FsRtlGetFileSize(), FsRtlNotifyCompleteIrpList(), FsRtlNotifyCompletion(), FsRtlOpBatchBreakClosePending(), FsRtlOplockBreakNotify(), FsRtlOplockBreakToII(), FsRtlOplockBreakToNone(), FsRtlOplockCleanup(), FsRtlOplockFsctrl(), FsRtlPrivateCancelFileLockIrp(), FsRtlPrivateCheckWaitingLocks(), FsRtlPrivateLock(), FsRtlProcessFileLock(), FsRtlRemoveAndCompleteIrp(), FsRtlRemoveAndCompleteWaitIrp(), FsRtlRequestExclusiveOplock(), FsRtlRequestOplockII(), FsRtlSetFileSize(), FsRtlSyncVolumes(), FsRtlUninitializeFileLock(), FsRtlUninitializeOplock(), FsRtlWaitOnIrp(), FsVgaDeviceControl(), FsVgaOpenCloseDispatch(), IoAllocateMdl(), IoAsynchronousPageWrite(), IoCallDriver(), IoCancelIrp(), IoCompleteRequest(), IoEnqueueIrp(), IoErrInitErrLogByIrp(), IoErrLogErrByIrp(), IofCallDriver(), IofCompleteRequest(), IoFreeDumpStack(), IoFreeIrp(), IoGetRequestorProcess(), IoGetRequestorProcessId(), IoGetRequestorSessionId(), IoInitializeIrp(), IoIsOperationSynchronous(), IoIsValidNameGraftingBuffer(), IoMakeAssociatedIrp(), IopCancelAlertedRequest(), IopDeleteIoCompletion(), IopDeviceEjectComplete(), IopDeviceRelationsComplete(), IopDeviceStartComplete(), IopDoNameTransmogrify(), IopDropIrp(), IopExceptionCleanup(), IopfCallDriver(), IopFreeIrp(), IopFreeIrpAndMdls(), IopGetDumpStack(), IopInvalidDeviceRequest(), IopOpenLinkOrRenameTarget(), IopPnPCompleteRequest(), IopPnPDispatch(), IopPowerDispatch(), IopStartApcHardError(), IopSynchronousApiServiceTail(), IopSynchronousServiceTail(), IoQueueThreadIrp(), IoRaiseHardError(), IoReuseIrp(), IoSetHardErrorOrVerifyDevice(), IoSetTopLevelIrp(), IoStartPacket(), IovBuildAsynchronousFsdRequest(), IovBuildDeviceIoControlRequest(), IovCallDriver(), IovCancelIrp(), IovCompleteRequest(), IovFreeIrp(), IovFreeIrpPrivate(), IovInitializeIrp(), IovpAllocateIrp2(), IovpCancelIrp(), IovpCompleteRequest1(), IovpCompleteRequest2(), IovpCompleteRequest3(), IovpCompleteRequest4(), IovpCompleteRequestApc(), IovpExamineIrpStackForwarding(), IovpFreeIrp(), IovpInitializeIrp(), IovpInternalCompletionTrap(), IovpInternalDeferredCompletion(), IovpProtectedIrpMakeTouchable(), IovpProtectedIrpMakeUntouchable(), IovpSwapSurrogateIrp(), IovpTrackingDataCreateAndLock(), IovpTrackingDataFindAndLock(), IovpTrackingDataFindPointer(), IovpWatermarkIrp(), IovSpecialIrpCallDriver(), NtfsRecFsControl(), NtRemoveIoCompletion(), UdfAddToWorkque(), UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteMdl(), UdfCompleteRequest(), UdfCreateIrpContext(), UdfDevCtrlCompletionRoutine(), UdfDismountVolume(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfFsdDispatch(), UdfFsdPostRequest(), UdfFspDispatch(), UdfInvalidateVolumes(), UdfIsPathnameValid(), UdfIsVolumeDirty(), UdfIsVolumeMounted(), UdfLockVolume(), UdfMountVolume(), UdfMultiAsyncCompletionRoutine(), UdfMultipleAsync(), UdfMultiSyncCompletionRoutine(), UdfNotifyChangeDirectory(), UdfOplockComplete(), UdfOplockRequest(), UdfPerformDevIoCtrl(), UdfPerformVerify(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfPrepareBuffers(), UdfPrePostIrp(), UdfProcessException(), UdfQueryDirectory(), UdfReadSectors(), UdfSingleAsyncCompletionRoutine(), UdfSingleSyncCompletionRoutine(), UdfsRecFsControl(), UdfUnlockVolume(), UdfUserFsctl(), and UdfVerifyVolume().

typedef struct _LINK_TRACKING_PACKET LINK_TRACKING_PACKET

| Referenced by IopSendMessageToTrackService().

typedef struct _LOAD_PACKET LOAD_PACKET

| Referenced by IopCompleteUnloadOrDelete().

typedef struct _MINIPORT_NODE MINIPORT_NODE

| Referenced by IopInitializeDCB().

typedef struct _NOTIFICATION_PACKET NOTIFICATION_PACKET

typedef struct _OPEN_PACKET OPEN_PACKET

| Referenced by IoFastQueryNetworkAttributes(), NtDeleteFile(), NtQueryAttributesFile(), and NtQueryFullAttributesFile().

typedef enum _COMPLETION_PACKET_TYPE * PCOMPLETION_PACKET_TYPE

typedef struct _DUMMY_FILE_OBJECT * PDUMMY_FILE_OBJECT

typedef struct _DUMP_CONTROL_BLOCK * PDUMP_CONTROL_BLOCK

typedef struct _ERROR_LOG_ENTRY * PERROR_LOG_ENTRY

| Referenced by IopErrorLogThread().

typedef PIRP(* PIO_ALLOCATE_IRP)(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)

| Definition at line 147 of file iop.h.

typedef VOID(* PIO_FREE_IRP)(IN struct _IRP *Irp)

| Definition at line 141 of file iop.h.

typedef struct _IOP_APC_HARD_ERROR_PACKET * PIOP_APC_HARD_ERROR_PACKET

| Referenced by IopApcHardError().

typedef struct _IOP_HARD_ERROR_PACKET * PIOP_HARD_ERROR_PACKET

| Referenced by IopHardErrorThread().

typedef struct _IOP_HARD_ERROR_QUEUE * PIOP_HARD_ERROR_QUEUE

typedef struct _IOP_MINI_COMPLETION_PACKET * PIOP_MINI_COMPLETION_PACKET

typedef struct _LINK_TRACKING_PACKET * PLINK_TRACKING_PACKET

| Referenced by IopConnectLinkTrackingPort().

typedef struct _LOAD_PACKET * PLOAD_PACKET

| Referenced by IopLoadUnloadDriver().

typedef struct _MINIPORT_NODE * PMINIPORT_NODE

typedef struct _NOTIFICATION_PACKET * PNOTIFICATION_PACKET

typedef struct _OPEN_PACKET * POPEN_PACKET

typedef struct _REINIT_PACKET * PREINIT_PACKET

| Referenced by IopLoadUnloadDriver().

typedef IN CCHAR PriorityBoost

| Definition at line 137 of file iop.h. Referenced by IoCompleteRequest(), IofCompleteRequest(), IovCompleteRequest(), and IovpCompleteRequest1().

typedef struct _SHUTDOWN_PACKET * PSHUTDOWN_PACKET

typedef enum _TRANSFER_TYPE * PTRANSFER_TYPE

typedef struct _REINIT_PACKET REINIT_PACKET

| Referenced by IopLoadUnloadDriver().

typedef struct _SHUTDOWN_PACKET SHUTDOWN_PACKET

typedef enum _TRANSFER_TYPE TRANSFER_TYPE

| Referenced by IopSynchronousServiceTail().

## Enumeration Type Documentation

enum _COMPLETION_PACKET_TYPE

Enumeration values:

  IopCompletionPacketIrp |
  IopCompletionPacketMini |
  IopCompletionPacketQuota |

Definition at line 374 of file iop.h.

    00374                                      {
    00375     IopCompletionPacketIrp,
    00376     IopCompletionPacketMini,
    00377     IopCompletionPacketQuota
    00378 } COMPLETION_PACKET_TYPE, *PCOMPLETION_PACKET_TYPE;

enum _TRANSFER_TYPE

Enumeration values:

  ReadTransfer |
  WriteTransfer |
  OtherTransfer |

Definition at line 71 of file iop.h.

    00071                             {
    00072     ReadTransfer,
    00073     WriteTransfer,
    00074     OtherTransfer
    00075 } TRANSFER_TYPE, *PTRANSFER_TYPE;

## Function Documentation

VOID IopAbortRequest | ( | IN PKAPC | Apc | ) |

Definition at line 144 of file internal.c.

References IopCompleteRequest(), and PAGED_CODE.

Referenced by IoRaiseHardError().

    00150                    :
    00151
    00152     This routine is invoked to abort an I/O request.  It is invoked during the
    00153     rundown of a thread.
    00154
    00155 Arguments:
    00156
    00157     Apc - Pointer to the kernel APC structure.  This structure is contained
    00158         within the I/O Request Packet (IRP) itself.
    00159
    00160 Return Value:
    00161
    00162     None.
    00163
    00164 --*/
    00165
    00166 {
    00167     PAGED_CODE();
    00168
    00169     //
    00170     // Invoke the normal special kernel APC routine.
    00171     //
    00172
    00173     IopCompleteRequest( Apc,
    00174                         &Apc->NormalRoutine,
    00175                         &Apc->NormalContext,
    00176                         &Apc->SystemArgument1,
    00177                         &Apc->SystemArgument2 );
    00178 }

NTSTATUS IopAcquireFileObjectLock | ( | IN PFILE_OBJECT | FileObject,
|  | IN KPROCESSOR_MODE | RequestorMode,
|  | IN BOOLEAN | Alertable,
|  | OUT PBOOLEAN | Interrupted
| ) |

Definition at line 181 of file internal.c.

References Executive, FALSE, IopAcquireFastLock, KeSetEvent(), KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, and TRUE.

Referenced by BuildQueryDirectoryIrp(), IopCloseFile(), IopDeleteFile(), IopGetSetSecurityObject(), IopQueryXxxInformation(), IopSetEaOrQuotaInformationFile(), IopXxxControlFile(), IoSetInformation(), NtFlushBuffersFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetEaFile(), NtSetInformationFile(), NtSetVolumeInformationFile(), NtUnlockFile(), NtWriteFile(), and NtWriteFileGather().

    00190                    :
    00191
    00192     This routine is invoked to acquire the lock for a file object whenever
    00193     there is contention and obtaining the fast lock for the file failed.
    00194
    00195 Arguments:
    00196
    00197     FileObject - Pointer to the file object whose lock is to be acquired.
    00198
    00199     RequestorMode - Processor access mode of the caller.
    00200
    00201     Alertable - Indicates whether or not the lock should be obtained in an
    00202         alertable manner.
    00203
    00204     Interrupted - A variable to receive a BOOLEAN that indicates whether or
    00205         not the attempt to acquire the lock was interrupted by an alert or
    00206         an APC.
    00207
    00208 Return Value:
    00209
    00210     The function status is the final status of the operation.
    00211
    00212 --*/
    00213 {
    00214     NTSTATUS status;
    00215
    00216     PAGED_CODE();
    00217
    00218     //
    00219     // Assume that the function will not be interrupted by an alert or an
    00220     // APC while attempting to acquire the lock.
    00221     //
    00222
    00223     *Interrupted = FALSE;
    00224
    00225     //
    00226     // Loop attempting to acquire the lock for the file object.
    00227     //
    00228
    00229     InterlockedIncrement (&FileObject->Waiters);
    00230
    00231     for (;;) {
    00232         if (!FileObject->Busy) {
    00233
    00234             //
    00235             // The file object appears to be un-owned, try to acquire it
    00236             //
    00237
    00238             if (IopAcquireFastLock ( FileObject ) ) {
    00239
    00240                 //
    00241                 // Object was acquired. Remove our count and return success
    00242                 //
    00243
    00244                 InterlockedDecrement (&FileObject->Waiters);
    00245                 return STATUS_SUCCESS;
    00246             }
    00247         }
    00248
    00249         //
    00250         // Wait for the event that indicates that the thread that currently
    00251         // owns the file object has released it.
    00252         //
    00253
    00254         status = KeWaitForSingleObject( &FileObject->Lock,
    00255                                         Executive,
    00256                                         RequestorMode,
    00257                                         Alertable,
    00258                                         (PLARGE_INTEGER) NULL );
    00259
    00260         //
    00261         // If the above wait was interrupted, then indicate so and return.
    00262         // Before returning, however, check the state of the ownership of
    00263         // the file object itself.  If it is not currently owned (the busy
    00264         // flag is clear), then check to see whether or not there are any
    00265         // other waiters.  If so, then set the event to the signaled state
    00266         // again so that they wake up and check the state of the busy flag.
    00267         //
    00268
    00269         if (status == STATUS_USER_APC || status == STATUS_ALERTED) {
    00270             InterlockedDecrement (&FileObject->Waiters);
    00271
    00272             if (!FileObject->Busy  &&  FileObject->Waiters) {
    00273                 KeSetEvent( &FileObject->Lock, 0, FALSE );
    00274
    00275             }
    00276             *Interrupted = TRUE;
    00277             return status;
    00278         }
    00279     }
    00280 }

NTSTATUS IopAddRemoteBootValuesToRegistry | ( | PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 314 of file netboot.c.

References _LOADER_PARAMETER_BLOCK::ArcBootDeviceName, ASSERT, CHAR, CmRegistryMachineSystemCurrentControlSetServices, _SETUP_LOADER_BLOCK::ComputerName, _SETUP_LOADER_BLOCK::DefaultRouter, DWORD, FALSE, _SETUP_LOADER_BLOCK::Flags, IopOpenRegistryKey(), IopWriteIpAddressToRegistry(), _SETUP_LOADER_BLOCK::IpAddress, L, _SETUP_LOADER_BLOCK::MachineDirectoryPath, _SETUP_LOADER_BLOCK::NetbootCardDriverName, _SETUP_LOADER_BLOCK::NetbootCardServiceName, NT_SUCCESS, _LOADER_PARAMETER_BLOCK::NtBootPathName, NtClose(), NtDeleteValueKey(), NtOpenKey(), NtQueryValueKey(), NtSetValueKey(), NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlDnsHostNameToComputerName(), RtlFreeUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), SETUPBLK_FLAGS_IS_TEXTMODE, _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, _SETUP_LOADER_BLOCK::SubnetMask, TITLE_INDEX_VALUE, and TRUE.

Referenced by IoInitSystem().

    00317 {
    00318     NTSTATUS status = STATUS_SUCCESS;
    00319     HANDLE handle;
    00320     HANDLE serviceHandle;
    00321     OBJECT_ATTRIBUTES objectAttributes;
    00322     UNICODE_STRING string;
    00323     CHAR addressA[16];
    00324     WCHAR addressW[16];
    00325     STRING addressStringA;
    00326     UNICODE_STRING addressStringW;
    00327     PUCHAR addressPointer;
    00328     PUCHAR p;
    00329     PUCHAR q;
    00330     UCHAR ntName[128];
    00331     WCHAR imagePath[128];
    00332     STRING ansiString;
    00333     UNICODE_STRING unicodeString;
    00334     UNICODE_STRING dnsNameString;
    00335     UNICODE_STRING netbiosNameString;
    00336     ULONG tmpValue;
    00337
    00338     if (LoaderBlock->SetupLoaderBlock->ComputerName[0] != 0) {
    00339
    00340         //
    00341         // Convert the name to a Netbios name.
    00342         //
    00343
    00344         _wcsupr( LoaderBlock->SetupLoaderBlock->ComputerName );
    00345
    00346         RtlInitUnicodeString( &dnsNameString, LoaderBlock->SetupLoaderBlock->ComputerName );
    00347
    00348         status = RtlDnsHostNameToComputerName(
    00349                      &netbiosNameString,
    00350                      &dnsNameString,
    00351                      TRUE);            // allocate netbiosNameString
    00352
    00353         if ( !NT_SUCCESS(status) ) {
    00354             KdPrint(( "IopAddRemoteBootValuesToRegistry: Failed RtlDnsHostNameToComputerName: %x\n", status ));
    00355             goto cleanup;
    00356         }
    00357
    00358         //
    00359         // Add a value for the computername.
    00360         //
    00361
    00362         RtlInitUnicodeString( &string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName" );
    00363
    00364         InitializeObjectAttributes(
    00365             &objectAttributes,
    00366             &string,
    00367             OBJ_CASE_INSENSITIVE,
    00368             NULL,
    00369             NULL
    00370             );
    00371
    00372         status = NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
    00373         if ( !NT_SUCCESS(status) ) {
    00374             KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to open ComputerName key: %x\n", status ));
    00375             RtlFreeUnicodeString( &netbiosNameString );
    00376             goto cleanup;
    00377         }
    00378
    00379         RtlInitUnicodeString( &string, L"ComputerName" );
    00380
    00381         status = NtSetValueKey(
    00382                     handle,
    00383                     &string,
    00384                     0,
    00385                     REG_SZ,
    00386                     netbiosNameString.Buffer,
    00387                     netbiosNameString.Length + sizeof(WCHAR)
    00388                     );
    00389         NtClose( handle );
    00390         RtlFreeUnicodeString( &netbiosNameString );
    00391
    00392         if ( !NT_SUCCESS(status) ) {
    00393             KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to set ComputerName value: %x\n", status ));
    00394             goto cleanup;
    00395         }
    00396
    00397         //
    00398         // Add a value for the host name.
    00399         //
    00400
    00401         RtlInitUnicodeString( &string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters" );
    00402
    00403         InitializeObjectAttributes(
    00404             &objectAttributes,
    00405             &string,
    00406             OBJ_CASE_INSENSITIVE,
    00407             NULL,
    00408             NULL
    00409             );
    00410
    00411         status = NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
    00412         if ( !NT_SUCCESS(status) ) {
    00413             KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to open Tcpip\\Parameters key: %x\n", status ));
    00414             goto cleanup;
    00415         }
    00416
    00417         _wcslwr( LoaderBlock->SetupLoaderBlock->ComputerName );
    00418
    00419         RtlInitUnicodeString( &string, L"Hostname" );
    00420
    00421         status = NtSetValueKey(
    00422                     handle,
    00423                     &string,
    00424                     0,
    00425                     REG_SZ,
    00426                     LoaderBlock->SetupLoaderBlock->ComputerName,
    00427                     (wcslen(LoaderBlock->SetupLoaderBlock->ComputerName) + 1) * sizeof(WCHAR)
    00428                     );
    00429         NtClose( handle );
    00430         if ( !NT_SUCCESS(status) ) {
    00431             KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to set Hostname value: %x\n", status ));
    00432             goto cleanup;
    00433         }
    00434     }
    00435
    00436     //
    00437     //  If the UNC path to the system files is supplied then store it in the registry.
    00438     //
    00439
    00440     ASSERT( _stricmp(LoaderBlock->ArcBootDeviceName,"net(0)") == 0 );
    00441
    00442     RtlInitUnicodeString( &string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control" );
    00443
    00444     InitializeObjectAttributes(
    00445         &objectAttributes,
    00446         &string,
    00447         OBJ_CASE_INSENSITIVE,
    00448         NULL,
    00449         NULL
    00450         );
    00451
    00452     status = NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
    00453     if ( !NT_SUCCESS(status) ) {
    00454         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to open Control key: %x\n", status ));
    00455         goto skiproot;
    00456     }
    00457
    00458     p = strrchr( LoaderBlock->NtBootPathName, '\\' );   // find last separator
    00459     if ( (p != NULL) && (*(p+1) == 0) ) {
    00460
    00461         //
    00462         // NtBootPathName ends with a backslash, so we need to back up
    00463         // to the previous backslash.
    00464         //
    00465
    00466         q = p;
    00467         *q = 0;
    00468         p = strrchr( LoaderBlock->NtBootPathName, '\\' );   // find last separator
    00469         *q = '\\';
    00470     }
    00471     if ( p == NULL ) {
    00472         KdPrint(( "IopAddRemoteBootValuesToRegistry: malformed NtBootPathName: %s\n", LoaderBlock->NtBootPathName ));
    00473         NtClose( handle );
    00474         goto skiproot;
    00475     }
    00476     *p = 0;                                 // terminate \server\share\images\machine
    00477
    00478 #if defined(REMOTE_BOOT)
    00479     //
    00480     // Store the server path in the shared user data area. Note that we need
    00481     // to add an extra \ at the beginning of this path to make it a UNC name.
    00482     //
    00483
    00484     SharedUserData->RemoteBootServerPath[0] = L'\\';
    00485     RtlInitAnsiString( &ansiString, LoaderBlock->NtBootPathName );
    00486     unicodeString.MaximumLength = sizeof(SharedUserData->RemoteBootServerPath) - (2 * sizeof(WCHAR));
    00487     unicodeString.Buffer = &SharedUserData->RemoteBootServerPath[1];
    00488     RtlAnsiStringToUnicodeString( &unicodeString, &ansiString, FALSE );
    00489     SharedUserData->RemoteBootServerPath[1 + (unicodeString.Length/sizeof(WCHAR))] = 0;
    00490 #endif // defined(REMOTE_BOOT)
    00491
    00492     strcpy( ntName, "\\Device\\LanmanRedirector");
    00493     strcat( ntName, LoaderBlock->NtBootPathName );  // append \server\share\images\machine
    00494     *p = '\\';
    00495
    00496     RtlInitAnsiString( &ansiString, ntName );
    00497     RtlAnsiStringToUnicodeString( &unicodeString, &ansiString, TRUE );
    00498
    00499     RtlInitUnicodeString( &string, L"RemoteBootRoot" );
    00500
    00501     status = NtSetValueKey(
    00502                 handle,
    00503                 &string,
    00504                 0,
    00505                 REG_SZ,
    00506                 unicodeString.Buffer,
    00507                 unicodeString.Length + sizeof(WCHAR)
    00508                 );
    00509
    00510     RtlFreeUnicodeString( &unicodeString );
    00511     if ( !NT_SUCCESS(status) ) {
    00512         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to set RemoteBootRoot value: %x\n", status ));
    00513     }
    00514
    00515     if ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_IS_TEXTMODE) != 0) {
    00516
    00517         strcpy( ntName, "\\Device\\LanmanRedirector");
    00518         strcat( ntName, LoaderBlock->SetupLoaderBlock->MachineDirectoryPath );
    00519         RtlInitAnsiString( &ansiString, ntName );
    00520         RtlAnsiStringToUnicodeString( &unicodeString, &ansiString, TRUE );
    00521
    00522         RtlInitUnicodeString( &string, L"RemoteBootMachineDirectory" );
    00523
    00524         status = NtSetValueKey(
    00525                     handle,
    00526                     &string,
    00527                     0,
    00528                     REG_SZ,
    00529                     unicodeString.Buffer,
    00530                     unicodeString.Length + sizeof(WCHAR)
    00531                     );
    00532
    00533         RtlFreeUnicodeString( &unicodeString );
    00534         if ( !NT_SUCCESS(status) ) {
    00535             KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to set RemoteBootMachineDirectory value: %x\n", status ));
    00536         }
    00537     }
    00538
    00539     NtClose( handle );
    00540
    00541 skiproot:
    00542
    00543 #if defined(REMOTE_BOOT)
    00544     StartCsc = INIT_CSC;
    00545     IopSetFlushCSC(READ_CSC);
    00546
    00547     if ( (StartCsc != FLUSH_CSC) &&
    00548          ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_REPIN) != 0) ) {
    00549         StartCsc = FLUSH_CSC;
    00550         IopSetFlushCSC(SET_FLUSH_CSC);
    00551     }
    00552
    00553 #if 0
    00554     RtlInitUnicodeString( &string, L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CSCSettings" );
    00555
    00556     InitializeObjectAttributes(
    00557         &objectAttributes,
    00558         &string,
    00559         OBJ_CASE_INSENSITIVE,
    00560         NULL,
    00561         NULL
    00562         );
    00563
    00564     status = NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
    00565
    00566     if ( NT_SUCCESS(status) ) {
    00567
    00568         PKEY_VALUE_PARTIAL_INFORMATION keyValue;
    00569         UCHAR buffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + sizeof(DWORD)];
    00570         ULONG length;
    00571         DWORD disabled;
    00572
    00573 #define ONE_BOOT 2
    00574
    00575         RtlInitUnicodeString( &string, L"DisableAgent" );
    00576
    00577         if ( (LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_DISABLE_CSC) == 0 ) {
    00578
    00579             //
    00580             // Disable CSC for this boot.
    00581             //
    00582
    00583             disabled = ONE_BOOT;
    00584             status = NtSetValueKey(
    00585                         handle,
    00586                         &string,
    00587                         0,
    00588                         REG_DWORD,
    00589                         &disabled,
    00590                         sizeof(DWORD));
    00591
    00592         } else {
    00593
    00594             keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
    00595             status = NtQueryValueKey(
    00596                          handle,
    00597                          &string,
    00598                          KeyValuePartialInformation,
    00599                          keyValue,
    00600                          sizeof(buffer),
    00601                          &length);
    00602             if (NT_SUCCESS(status)) {
    00603                 disabled = *((DWORD *)(&keyValue->Data[0]));
    00604
    00605                 if (disabled == ONE_BOOT) {
    00606                     //  Only disabled for last boot so re-enable now.
    00607                     status = NtDeleteValueKey( handle, &string);
    00608                     //  BUGBUG should we repin?
    00609                 }
    00610             }
    00611         }
    00612
    00613         NtClose( handle );
    00614         if ( !NT_SUCCESS(status) ) {
    00615             KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to set CSCSettings: %x\n", status ));
    00616             goto cleanup;
    00617         }
    00618     }
    00619 #endif
    00620 #endif // defined(REMOTE_BOOT)
    00621
    00622     //
    00623     // Add registry values for the IP address and subnet mask received
    00624     // from DHCP. These are stored under the Tcpip service key and are
    00625     // read by both Tcpip and Netbt. The adapter name used is the known
    00626     // GUID for the NetbootCard.
    00627     //
    00628
    00629     RtlInitUnicodeString( &string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\{54C7D140-09EF-11D1-B25A-F5FE627ED95E}" );
    00630
    00631     InitializeObjectAttributes(
    00632         &objectAttributes,
    00633         &string,
    00634         OBJ_CASE_INSENSITIVE,
    00635         NULL,
    00636         NULL
    00637         );
    00638
    00639     status = NtOpenKey( &handle, KEY_ALL_ACCESS, &objectAttributes );
    00640     if ( !NT_SUCCESS(status) ) {
    00641         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to open Tcpip\\Parameters\\Interfaces\\{54C7D140-09EF-11D1-B25A-F5FE627ED95E} key: %x\n", status ));
    00642         goto cleanup;
    00643     }
    00644
    00645     status = IopWriteIpAddressToRegistry(handle,
    00646                                          L"DhcpIPAddress",
    00647                                          (PUCHAR)&(LoaderBlock->SetupLoaderBlock->IpAddress)
    00648                                         );
    00649
    00650     if ( !NT_SUCCESS(status)) {
    00651         NtClose(handle);
    00652         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to write DhcpIPAddress: %x\n", status ));
    00653         goto cleanup;
    00654     }
    00655
    00656     status = IopWriteIpAddressToRegistry(handle,
    00657                                          L"DhcpSubnetMask",
    00658                                          (PUCHAR)&(LoaderBlock->SetupLoaderBlock->SubnetMask)
    00659                                         );
    00660
    00661     if ( !NT_SUCCESS(status)) {
    00662         NtClose(handle);
    00663         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to write DhcpSubnetMask: %x\n", status ));
    00664         goto cleanup;
    00665     }
    00666
    00667     status = IopWriteIpAddressToRegistry(handle,
    00668                                          L"DhcpDefaultGateway",
    00669                                          (PUCHAR)&(LoaderBlock->SetupLoaderBlock->DefaultRouter)
    00670                                         );
    00671
    00672     NtClose(handle);
    00673
    00674     if ( !NT_SUCCESS(status)) {
    00675         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to write DhcpDefaultGateway: %x\n", status ));
    00676         goto cleanup;
    00677     }
    00678
    00679     //
    00680     // Create the service key for the netboot card. We need to have
    00681     // the Type value there or the card won't be initialized.
    00682     //
    00683
    00684     status = IopOpenRegistryKey(&handle,
    00685                                 NULL,
    00686                                 &CmRegistryMachineSystemCurrentControlSetServices,
    00687                                 KEY_ALL_ACCESS,
    00688                                 FALSE
    00689                                 );
    00690
    00691     if (!NT_SUCCESS(status)) {
    00692         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to open CurrentControlSet\\Services: %x\n", status ));
    00693         goto cleanup;
    00694     }
    00695
    00696     RtlInitUnicodeString(&string, LoaderBlock->SetupLoaderBlock->NetbootCardServiceName);
    00697
    00698     InitializeObjectAttributes(&objectAttributes,
    00699                                &string,
    00700                                OBJ_CASE_INSENSITIVE,
    00701                                handle,
    00702                                (PSECURITY_DESCRIPTOR)NULL
    00703                                );
    00704
    00705     status = ZwCreateKey(&serviceHandle,
    00706                          KEY_ALL_ACCESS,
    00707                          &objectAttributes,
    00708                          0,
    00709                          (PUNICODE_STRING)NULL,
    00710                          0,
    00711                          &tmpValue     // disposition
    00712                          );
    00713
    00714     ZwClose(handle);
    00715
    00716     if (!NT_SUCCESS(status)) {
    00717         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to open/create netboot card service key: %x\n", status ));
    00718         goto cleanup;
    00719     }
    00720
    00721     //
    00722     // Store the image path.
    00723     //
    00724
    00725     PiWstrToUnicodeString(&string, L"ImagePath");
    00726     wcscpy(imagePath, L"system32\\drivers\\");
    00727     wcscat(imagePath, LoaderBlock->SetupLoaderBlock->NetbootCardDriverName);
    00728
    00729     status = ZwSetValueKey(serviceHandle,
    00730                            &string,
    00731                            TITLE_INDEX_VALUE,
    00732                            REG_SZ,
    00733                            imagePath,
    00734                            (wcslen(imagePath) + 1) * sizeof(WCHAR)
    00735                            );
    00736
    00737     if (!NT_SUCCESS(status)) {
    00738         NtClose(serviceHandle);
    00739         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to write ImagePath: %x\n", status ));
    00740         goto cleanup;
    00741     }
    00742
    00743     //
    00744     // Store the type.
    00745     //
    00746
    00747     PiWstrToUnicodeString(&string, L"Type");
    00748     tmpValue = 1;
    00749
    00750     ZwSetValueKey(serviceHandle,
    00751                   &string,
    00752                   TITLE_INDEX_VALUE,
    00753                   REG_DWORD,
    00754                   &tmpValue,
    00755                   sizeof(tmpValue)
    00756                   );
    00757
    00758     NtClose(serviceHandle);
    00759
    00760     if (!NT_SUCCESS(status)) {
    00761         KdPrint(( "IopAddRemoteBootValuesToRegistry: Unable to write Type: %x\n", status ));
    00762     }
    00763
    00764 cleanup:
    00765
    00766     return status;
    00767 }

PVOID IopAllocateErrorLogEntry | ( | IN PDEVICE_OBJECT | deviceObject,
|  | IN PDRIVER_OBJECT | driverObject,
|  | IN UCHAR | EntrySize
| ) |

Definition at line 542 of file iosubs.c.

References _ERROR_LOG_ENTRY::DeviceObject, _ERROR_LOG_ENTRY::DriverObject, ExAllocatePoolWithTag, IO_TYPE_ERROR_LOG, IOP_MAXIMUM_LOG_ALLOCATION, IopErrorLogAllocation, IopErrorLogAllocationLock, NonPagedPool, NTSTATUS(), NULL, ObReferenceObject, _ERROR_LOG_ENTRY::Size, _ERROR_LOG_ENTRY::Type, and USHORT.

Referenced by IoAllocateErrorLogEntry(), and IoAllocateGenericErrorLogEntry().

    00547 {
    00548     PERROR_LOG_ENTRY elEntry;
    00549     PVOID returnValue;
    00550     NTSTATUS status;
    00551     KIRQL oldIrql;
    00552     ULONG size;
    00553
    00554     //
    00555     // Make sure the packet is large enough but not too large.
    00556     //
    00557
    00558     if (EntrySize < sizeof(IO_ERROR_LOG_PACKET) ||
    00559         EntrySize > ERROR_LOG_MAXIMUM_SIZE) {
    00560
    00561         return(NULL);
    00562     }
    00563
    00564     //
    00565     // Round entry size to a PVOID size boundary.
    00566     //
    00567
    00568     EntrySize = (UCHAR) ((EntrySize + sizeof(PVOID) - 1) & ~(sizeof(PVOID) - 1));
    00569
    00570     //
    00571     // Calculate the size of the entry needed.
    00572     //
    00573
    00574     size = sizeof(ERROR_LOG_ENTRY) + EntrySize;
    00575
    00576     //
    00577     // Make sure that there are not too many outstanding packets.
    00578     //
    00579
    00580     ExAcquireSpinLock(&IopErrorLogAllocationLock, &oldIrql);
    00581
    00582     try{
    00583
    00584         if (IopErrorLogAllocation > IOP_MAXIMUM_LOG_ALLOCATION) {
    00585
    00586             //
    00587             // Fail the request.
    00588             //
    00589
    00590             return(NULL);
    00591         }
    00592
    00593         //
    00594         // Increase the outstanding allocation.
    00595         //
    00596
    00597         IopErrorLogAllocation += size;
    00598
    00599         //
    00600         // Allocate the packet.
    00601         //
    00602
    00603         elEntry = ExAllocatePoolWithTag( NonPagedPool, size, 'rEoI' );
    00604
    00605         if (elEntry == NULL) {
    00606
    00607             //
    00608             // Drop the allocation and return.
    00609             //
    00610
    00611             IopErrorLogAllocation -= size;
    00612
    00613             return(NULL);
    00614         }
    00615
    00616         //
    00617         // Reference the device object and driver object. So they don't
    00618         // go away before the name gets pulled out.
    00619         //
    00620
    00621         if (deviceObject != NULL) {
    00622
    00623             ObReferenceObject( deviceObject );
    00624         }
    00625
    00626         if (driverObject != NULL) {
    00627
    00628             ObReferenceObject( driverObject );
    00629         }
    00630
    00631         //
    00632         // Initialize the fields.
    00633         //
    00634
    00635         RtlZeroMemory(elEntry, size);
    00636
    00637         elEntry->Type = IO_TYPE_ERROR_LOG;
    00638         elEntry->Size = (USHORT) size;
    00639         elEntry->DeviceObject = deviceObject;
    00640         elEntry->DriverObject = driverObject;
    00641
    00642         returnValue = elEntry+1;
    00643
    00644     } finally {
    00645         ExReleaseSpinLock(&IopErrorLogAllocationLock, oldIrql);
    00646     }
    00647
    00648     return returnValue;
    00649 }

VOID IopAllocateIrpCleanup | ( | IN PFILE_OBJECT | FileObject,
|  | IN PKEVENT EventObject | OPTIONAL
| ) |

Definition at line 284 of file internal.c.

References FO_SYNCHRONOUS_IO, IopReleaseFileObjectLock, ObDereferenceObject, and PAGED_CODE.

Referenced by BuildQueryDirectoryIrp(), IopGetFileName(), IopGetSetSecurityObject(), IopQueryXxxInformation(), IopSetEaOrQuotaInformationFile(), IopXxxControlFile(), IoSetInformation(), NtFlushBuffersFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetEaFile(), NtSetInformationFile(), NtSetVolumeInformationFile(), NtUnlockFile(), NtWriteFile(), and NtWriteFileGather().

    00291                    :
    00292
    00293     This routine is invoked internally by those system services that attempt
    00294     to allocate an IRP and fail.  This routine cleans up the file object
    00295     and any event object that has been references and releases any locks
    00296     that were taken out.
    00297
    00298 Arguments:
    00299
    00300     FileObject - Pointer to the file object being worked on.
    00301
    00302     EventObject - Optional pointer to a referenced event to be dereferenced.
    00303
    00304 Return Value:
    00305
    00306     None.
    00307
    00308 --*/
    00309
    00310 {
    00311     PAGED_CODE();
    00312
    00313     //
    00314     // Begin by dereferencing the event, if one was specified.
    00315     //
    00316
    00317     if (ARGUMENT_PRESENT( EventObject )) {
    00318         ObDereferenceObject( EventObject );
    00319     }
    00320
    00321     //
    00322     // Release the synchronization semaphore if it is currently held and
    00323     // dereference the file object.
    00324     //
    00325
    00326     if (FileObject->Flags & FO_SYNCHRONOUS_IO) {
    00327         IopReleaseFileObjectLock( FileObject );
    00328     }
    00329
    00330     ObDereferenceObject( FileObject );
    00331
    00332     return;
    00333 }

PIRP IopAllocateIrpMustSucceed | ( | IN CCHAR | StackSize | ) |

Definition at line 336 of file internal.c.

References _IRP::AllocationFlags, ExAllocatePoolWithTag, FALSE, IoAllocateIrp(), IoInitializeIrp(), IoSizeOfIrp, IRP_ALLOCATED_MUST_SUCCEED, NonPagedPoolMustSucceed, and USHORT.

Referenced by IoCancelFileOpen(), IopCloseFile(), IopDeleteFile(), and IopMountVolume().

    00342                    :
    00343
    00344     This routine is invoked to allocate an IRP when there are no appropriate
    00345     packets remaining on the look-aside list, and no memory was available
    00346     from the general non-paged pool, and yet, the code path requiring the
    00347     packet has no way of backing out and simply returning an error.  There-
    00348     fore, it must allocate an IRP.  Hence, this routine is called to allocate
    00349     that packet.
    00350
    00351 Arguments:
    00352
    00353     StackSize - Supplies the number of IRP I/O stack locations that the
    00354         packet must have when allocated.
    00355
    00356 Return Value:
    00357
    00358     A pointer to the allocated I/O Request Packet.
    00359
    00360 --*/
    00361
    00362 {
    00363     PIRP irp;
    00364     USHORT packetSize;
    00365
    00366     //
    00367     // Attempt to allocate the IRP normally and failing that, allocate the
    00368     // IRP from nonpaged must succeed pool.
    00369     //
    00370
    00371     irp = IoAllocateIrp(StackSize, FALSE);
    00372     if (!irp) {
    00373         packetSize = IoSizeOfIrp(StackSize);
    00374         irp = ExAllocatePoolWithTag(NonPagedPoolMustSucceed, packetSize, ' prI');
    00375         IoInitializeIrp(irp, packetSize, StackSize);
    00376         irp->AllocationFlags |= IRP_ALLOCATED_MUST_SUCCEED;
    00377     }
    00378
    00379     return irp;
    00380 }

PIRP IopAllocateIrpPrivate | ( | IN CCHAR | StackSize,
|  | IN BOOLEAN | ChargeQuota
| ) |

Definition at line 662 of file iosubs.c.

References _GENERAL_LOOKASIDE::AllocateMisses, _IRP::AllocationFlags, ExAllocatePoolWithQuotaTag, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, ExInterlockedPopEntrySList(), FALSE, IopInitializeIrp, IopLargeIrpStackLocations, IopLookasideIrpFloat, IopLookasideIrpLimit, IoSizeOfIrp, IRP_ALLOCATED_FIXED_SIZE, IRP_ALLOCATED_MUST_SUCCEED, IRP_LOOKASIDE_ALLOCATION, IRP_QUOTA_CHARGED, KeGetCurrentPrcb, KernelMode, _NPAGED_LOOKASIDE_LIST::L, _GENERAL_LOOKASIDE::ListHead, _NPAGED_LOOKASIDE_LIST::Lock, LookasideLargeIrpList, LookasideSmallIrpList, NonPagedPool, NonPagedPoolMustSucceed, NULL, PP_NPAGED_LOOKASIDE_NUMBER, _GENERAL_LOOKASIDE::TotalAllocates, and USHORT.

Referenced by IopSetIoRoutines(), and IovAllocateIrp().

    00669                    :
    00670
    00671     This routine allocates an I/O Request Packet from the system nonpaged pool.
    00672     The packet will be allocated to contain StackSize stack locations.  The IRP
    00673     will also be initialized.
    00674
    00675 Arguments:
    00676
    00677     StackSize - Specifies the maximum number of stack locations required.
    00678
    00679     ChargeQuota - Specifies whether quota should be charged against thread.
    00680
    00681 Return Value:
    00682
    00683     The function value is the address of the allocated/initialized IRP,
    00684     or NULL if one could not be allocated.
    00685
    00686 --*/
    00687
    00688 {
    00689     USHORT allocateSize;
    00690     UCHAR fixedSize;
    00691     PIRP irp;
    00692     UCHAR lookasideAllocation;
    00693     PNPAGED_LOOKASIDE_LIST lookasideList;
    00694     UCHAR mustSucceed;
    00695     PP_NPAGED_LOOKASIDE_NUMBER number;
    00696     USHORT packetSize;
    00697     PKPRCB prcb;
    00698
    00699     //
    00700     // If the size of the packet required is less than or equal to those on
    00701     // the lookaside lists, then attempt to allocate the packet from the
    00702     // lookaside lists.
    00703     //
    00704
    00705     irp = NULL;
    00706     fixedSize = 0;
    00707     mustSucceed = 0;
    00708     packetSize = IoSizeOfIrp(StackSize);
    00709     allocateSize = packetSize;
    00710     if ((StackSize <= (CCHAR)IopLargeIrpStackLocations) &&
    00711         ((ChargeQuota == FALSE) || (IopLookasideIrpFloat < IopLookasideIrpLimit))) {
    00712         fixedSize = IRP_ALLOCATED_FIXED_SIZE;
    00713         number = LookasideSmallIrpList;
    00714         if (StackSize != 1) {
    00715             allocateSize = IoSizeOfIrp((CCHAR)IopLargeIrpStackLocations);
    00716             number = LookasideLargeIrpList;
    00717         }
    00718
    00719         prcb = KeGetCurrentPrcb();
    00720         lookasideList = prcb->PPLookasideList[number].P;
    00721         lookasideList->L.TotalAllocates += 1;
    00722         irp = (PIRP)ExInterlockedPopEntrySList(&lookasideList->L.ListHead,
    00723                                                &lookasideList->Lock);
    00724
    00725         if (irp == NULL) {
    00726             lookasideList->L.AllocateMisses += 1;
    00727             lookasideList = prcb->PPLookasideList[number].L;
    00728             lookasideList->L.TotalAllocates += 1;
    00729             irp = (PIRP)ExInterlockedPopEntrySList(&lookasideList->L.ListHead,
    00730                                                    &lookasideList->Lock);
    00731         }
    00732     }
    00733
    00734     //
    00735     // If an IRP was not allocated from the lookaside list, then allocate
    00736     // the packet from nonpaged pool and charge quota if requested.
    00737     //
    00738
    00739     lookasideAllocation = 0;
    00740     if (!irp) {
    00741         if (fixedSize != 0) {
    00742             lookasideList->L.AllocateMisses += 1;
    00743         }
    00744
    00745         //
    00746         // There are no free packets on the lookaside list, or the packet is
    00747         // too large to be allocated from one of the lists, so it must be
    00748         // allocated from nonpaged pool. If quota is to be charged, charge it
    00749         // against the current process. Otherwise, allocate the pool normally.
    00750         //
    00751
    00752         if (ChargeQuota) {
    00753             try {
    00754                 irp = ExAllocatePoolWithQuotaTag(NonPagedPool, allocateSize,' prI');
    00755
    00756             } except(EXCEPTION_EXECUTE_HANDLER) {
    00757                 NOTHING;
    00758             }
    00759
    00760         } else {
    00761
    00762             //
    00763             // Attempt to allocate the pool from non-paged pool.  If this
    00764             // fails, and the caller's previous mode was kernel then allocate
    00765             // the pool as must succeed.
    00766             //
    00767
    00768             irp = ExAllocatePoolWithTag(NonPagedPool, allocateSize, ' prI');
    00769             if (!irp) {
    00770                 mustSucceed = IRP_ALLOCATED_MUST_SUCCEED;
    00771                 if (KeGetPreviousMode() == KernelMode ) {
    00772                     irp = ExAllocatePoolWithTag(NonPagedPoolMustSucceed,
    00773                                                 allocateSize,
    00774                                                 ' prI');
    00775                 }
    00776             }
    00777         }
    00778
    00779         if (!irp) {
    00780             return NULL;
    00781         }
    00782
    00783     } else {
    00784         if (ChargeQuota != FALSE) {
    00785             lookasideAllocation = IRP_LOOKASIDE_ALLOCATION;
    00786             InterlockedIncrement( &IopLookasideIrpFloat );
    00787         }
    00788         ChargeQuota = FALSE;
    00789     }
    00790
    00791     //
    00792     // Initialize the packet.
    00793     //
    00794
    00795     IopInitializeIrp(irp, packetSize, StackSize);
    00796     irp->AllocationFlags = (fixedSize | lookasideAllocation | mustSucceed);
    00797     if (ChargeQuota) {
    00798         irp->AllocationFlags |= IRP_QUOTA_CHARGED;
    00799     }
    00800
    00801     return irp;
    00802 }

VOID IopApcHardError | ( | IN PVOID | StartContext | ) |

Definition at line 383 of file internal.c.

References ExFreePool(), IopRaiseHardError(), _IOP_APC_HARD_ERROR_PACKET::Irp, PIOP_APC_HARD_ERROR_PACKET, _IOP_APC_HARD_ERROR_PACKET::RealDeviceObject, and _IOP_APC_HARD_ERROR_PACKET::Vpb.

Referenced by IopStartApcHardError().

    00389                    :
    00390
    00391     This function is invoked when we need to do a hard error pop-up, but the
    00392     Irp's originating thread is at APC level, ie. IoPageRead.  We in a special
    00393     purpose thread that will go away when the user responds to the pop-up.
    00394
    00395 Arguments:
    00396
    00397     StartContext - Startup context, contains a IOP_APC_HARD_ERROR_PACKET.
    00398
    00399 Return Value:
    00400
    00401     None.
    00402
    00403 --*/
    00404
    00405 {
    00406     PIOP_APC_HARD_ERROR_PACKET packet;
    00407
    00408     packet = StartContext;
    00409
    00410     IopRaiseHardError( packet->Irp, packet->Vpb, packet->RealDeviceObject );
    00411
    00412     ExFreePool( packet );
    00413 }

VOID IopCancelAlertedRequest | ( | IN PKEVENT | Event,
|  | IN PIRP | Irp
| ) |

Definition at line 417 of file internal.c.

References APC_LEVEL, Event(), Executive, FALSE, IoCancelIrp(), Irp, KeDelayExecutionThread(), KeLowerIrql(), KeRaiseIrql(), KeReadStateEvent(), KernelMode, KeWaitForSingleObject(), NULL, PAGED_CODE, and VOID().

Referenced by IopQueryXxxInformation(), IopSynchronousApiServiceTail(), IopSynchronousServiceTail(), IoSetInformation(), NtQueryInformationFile(), and NtSetInformationFile().

    00424                    :
    00425
    00426     This routine is invoked when a synchronous I/O operation that is blocked in
    00427     the I/O system needs to be canceled because the thread making the request has
    00428     either been alerted because it is going away or because of a CTRL/C.  This
    00429     routine carefully attempts to work its way out of the current operation so
    00430     that local events or other local data will not be accessed once the service
    00431     being interrupted returns.
    00432
    00433 Arguments:
    00434
    00435     Event - The address of a kernel event that will be set to the Signaled state
    00436         by I/O completion when the request is complete.
    00437
    00438     Irp - Pointer to the I/O Request Packet (IRP) representing the current request.
    00439
    00440 Return Value:
    00441
    00442     None.
    00443
    00444 --*/
    00445
    00446 {
    00447     KIRQL irql;
    00448     LARGE_INTEGER deltaTime;
    00449     BOOLEAN canceled;
    00450
    00451     PAGED_CODE();
    00452
    00453     //
    00454     // Begin by blocking special kernel APCs so that the request cannot
    00455     // complete.
    00456     //
    00457
    00458     KeRaiseIrql( APC_LEVEL, &irql );
    00459
    00460     //
    00461     // Check the state of the event to determine whether or not the
    00462     // packet has already been completed.
    00463     //
    00464
    00465     if (KeReadStateEvent( Event ) == 0) {
    00466
    00467         //
    00468         // The packet has not been completed, so attempt to cancel it.
    00469         //
    00470
    00471         canceled = IoCancelIrp( Irp );
    00472
    00473         KeLowerIrql( irql );
    00474
    00475         if (canceled) {
    00476
    00477             //
    00478             // The packet had a cancel routine, so it was canceled.  Loop,
    00479             // waiting for the packet to complete.  This should occur almost
    00480             // immediately.
    00481             //
    00482
    00483             deltaTime.QuadPart = - 10 * 1000 * 10;
    00484
    00485             while (KeReadStateEvent( Event ) == 0) {
    00486
    00487                 KeDelayExecutionThread( KernelMode, FALSE, &deltaTime );
    00488
    00489             }
    00490
    00491         } else {
    00492
    00493             //
    00494             // The packet did not have a cancel routine, so simply wait for
    00495             // the event to be set to the Signaled state.  This will save
    00496             // CPU time by not looping, since it is not known when the packet
    00497             // will actually complete.  Note, however, that the cancel flag
    00498             // is set in the packet, so should a driver examine the flag
    00499             // at some point in the future, it will immediately stop
    00500             // processing the request.
    00501             //
    00502
    00503             (VOID) KeWaitForSingleObject( Event,
    00504                                           Executive,
    00505                                           KernelMode,
    00506                                           FALSE,
    00507                                           (PLARGE_INTEGER) NULL );
    00508
    00509         }
    00510
    00511     } else {
    00512
    00513         //
    00514         // The packet has already been completed, so simply lower the
    00515         // IRQL back to its original value and exit.
    00516         //
    00517
    00518         KeLowerIrql( irql );
    00519
    00520     }
    00521 }

VOID IopCheckBackupRestorePrivilege | ( | IN PACCESS_STATE | AccessState,
|  | IN OUT PULONG | CreateOptions,
|  | IN KPROCESSOR_MODE | PreviousMode,
|  | IN ULONG | Disposition
| ) |

Definition at line 2048 of file parse.c.

References FALSE, PAGED_CODE, SE_BACKUP_PRIVILEGES_CHECKED, SeAppendPrivileges(), SeBackupPrivilege, SePrivilegeCheck(), SeRestorePrivilege, TOKEN_HAS_BACKUP_PRIVILEGE, TOKEN_HAS_RESTORE_PRIVILEGE, TRUE, and VOID().

Referenced by IopParseDevice().

    02057                    :
    02058
    02059     This funcion will determine if the caller is asking for any accesses
    02060     that may be satisfied by Backup or Restore privileges, and if so,
    02061     perform the privilge checks.  If the privilege checks succeed, then
    02062     the appropriate bits will be moved out of the RemainingDesiredAccess
    02063     field in the AccessState structure and placed into the PreviouslyGrantedAccess
    02064     field.
    02065
    02066     Note that access is not denied if the caller does not have either or
    02067     both of the privileges, since he may be granted the desired access
    02068     via the security descriptor on the object.
    02069
    02070     This routine will also set a flag in the AccessState structure so that
    02071     it will not perform these privilege checks again in case we come through
    02072     this way again due to a reparse.
    02073
    02074 Arguments:
    02075
    02076     AccessState - The AccessState containing the current state of this access
    02077         attempt.
    02078
    02079     CreateOptions - The CreateOptions field from the OPEN_PACKET structure for
    02080         this open attempt.
    02081
    02082     PreviousMode - The processor mode to be used in checking parameters.
    02083
    02084     Disposition - The create disposition for this request.
    02085
    02086 Return Value:
    02087
    02088     None.
    02089
    02090 --*/
    02091
    02092 {
    02093     ACCESS_MASK desiredAccess;
    02094     ACCESS_MASK readAccess;
    02095     ACCESS_MASK writeAccess;
    02096     PRIVILEGE_SET requiredPrivileges;
    02097     BOOLEAN accessGranted;
    02098     BOOLEAN keepBackupIntent = FALSE;
    02099     BOOLEAN ForceRestoreCheck = FALSE;
    02100
    02101     PAGED_CODE();
    02102
    02103     //
    02104     // Check to determine whether or not this check has already been made.
    02105     // If so, simply return back to the caller.
    02106     //
    02107
    02108     if (AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED) {
    02109         return;
    02110     }
    02111
    02112     if (*CreateOptions & FILE_OPEN_FOR_BACKUP_INTENT) {
    02113         AccessState->Flags |= SE_BACKUP_PRIVILEGES_CHECKED;
    02114
    02115         readAccess = READ_CONTROL | ACCESS_SYSTEM_SECURITY | FILE_GENERIC_READ | FILE_TRAVERSE;
    02116         writeAccess = WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY | FILE_GENERIC_WRITE | FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | DELETE;
    02117
    02118         desiredAccess = AccessState->RemainingDesiredAccess;
    02119
    02120         //
    02121         // If the caller has requested MAXIMUM_ALLOWED, then make it appear as
    02122         // if the request was for everything permitted by Backup and Restore,
    02123         // and then grant everything that can actually be granted.
    02124         //
    02125
    02126         if (desiredAccess & MAXIMUM_ALLOWED) {
    02127             desiredAccess |= ( readAccess | writeAccess );
    02128         }
    02129
    02130         //
    02131         // If the disposition says that we're opening the file, check for both backup
    02132         // and restore privilege, depending on what's in the desired access.
    02133         //
    02134         // If the disposition says that we're creating or trying to overwrite the file,
    02135         // then all we need to do is to check for restore privilege, and if it's there,
    02136         // grant every possible access.
    02137         //
    02138
    02139         if ( Disposition & FILE_OPEN ) {
    02140
    02141             //
    02142             // If the request was for any of the bits in the read access mask, then
    02143             // assume that this is a backup operation, and check for the Backup
    02144             // privielege.  If the caller has it, then grant the intersection of
    02145             // the desired access and read access masks.
    02146             //
    02147
    02148             if (readAccess & desiredAccess) {
    02149
    02150                 requiredPrivileges.PrivilegeCount = 1;
    02151                 requiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
    02152                 requiredPrivileges.Privilege[0].Luid = SeBackupPrivilege;
    02153                 requiredPrivileges.Privilege[0].Attributes = 0;
    02154
    02155                 accessGranted = SePrivilegeCheck( &requiredPrivileges,
    02156                                                   &AccessState->SubjectSecurityContext,
    02157                                                   PreviousMode );
    02158
    02159                 if (accessGranted) {
    02160
    02161                     //
    02162                     // The caller has Backup privilege, so grant the appropriate
    02163                     // accesses.
    02164                     //
    02165
    02166                     keepBackupIntent = TRUE;
    02167                     (VOID) SeAppendPrivileges( AccessState, &requiredPrivileges );
    02168                     AccessState->PreviouslyGrantedAccess |= ( desiredAccess & readAccess );
    02169                     AccessState->RemainingDesiredAccess &= ~readAccess;
    02170                     desiredAccess &= ~readAccess;
    02171                     AccessState->Flags |= TOKEN_HAS_BACKUP_PRIVILEGE;
    02172                 }
    02173             }
    02174
    02175         } else {
    02176
    02177             ForceRestoreCheck = TRUE;
    02178         }
    02179
    02180         //
    02181         // If the request was for any of the bits in the write access mask, then
    02182         // assume that this is a restore operation, so check for the Restore
    02183         // privilege.  If the caller has it, then grant the intersection of
    02184         // the desired access and write access masks.
    02185         //
    02186
    02187         if ((writeAccess & desiredAccess) || ForceRestoreCheck) {
    02188
    02189             requiredPrivileges.PrivilegeCount = 1;
    02190             requiredPrivileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
    02191             requiredPrivileges.Privilege[0].Luid = SeRestorePrivilege;
    02192             requiredPrivileges.Privilege[0].Attributes = 0;
    02193
    02194             accessGranted = SePrivilegeCheck( &requiredPrivileges,
    02195                                               &AccessState->SubjectSecurityContext,
    02196                                               PreviousMode );
    02197
    02198             if (accessGranted) {
    02199
    02200                 //
    02201                 // The caller has Restore privilege, so grant the appropriate
    02202                 // accesses.
    02203                 //
    02204
    02205                 keepBackupIntent = TRUE;
    02206                 (VOID) SeAppendPrivileges( AccessState, &requiredPrivileges );
    02207                 AccessState->PreviouslyGrantedAccess |= (desiredAccess & writeAccess);
    02208                 AccessState->RemainingDesiredAccess &= ~writeAccess;
    02209                 AccessState->Flags |= TOKEN_HAS_RESTORE_PRIVILEGE;
    02210             }
    02211         }
    02212
    02213         //
    02214         // If either of the access types was granted because the caller had
    02215         // backup or restore privilege, then the backup intent flag is kept.
    02216         // Otherwise, it is cleared so that it is not passed onto the driver
    02217         // so that it is not incorrectly propogated anywhere else, since this
    02218         // caller does not actually have the privilege enabled.
    02219         //
    02220
    02221         if (!keepBackupIntent) {
    02222             *CreateOptions &= ~FILE_OPEN_FOR_BACKUP_INTENT;
    02223         }
    02224     }
    02225 }
    }

NTSTATUS IopCheckGetQuotaBufferValidity | ( | IN PFILE_GET_QUOTA_INFORMATION | QuotaBuffer,
|  | IN ULONG | QuotaLength,
|  | OUT PULONG_PTR | ErrorOffset
| ) |

Definition at line 524 of file internal.c.

References GET_OFFSET_LENGTH, PAGED_CODE, RtlLengthSid(), and RtlValidSid().

Referenced by NtQueryQuotaInformationFile().

    00532                    :
    00533
    00534     This routine checks the validity of the specified get quota buffer to
    00535     guarantee that its format is proper, no fields hang over, that it is
    00536     not recursive, etc.
    00537
    00538 Arguments:
    00539
    00540     QuotaBuffer - Pointer to the buffer containing the get quota structure
    00541         array to be checked.
    00542
    00543     QuotaLength - Specifies the length of the quota buffer.
    00544
    00545     ErrorOffset - A variable to receive the offset of the offending entry
    00546         in the quota buffer if an error is incurred.  This variable is only
    00547         valid if an error occurs.
    00548
    00549 Return Value:
    00550
    00551     The function value is STATUS_SUCCESS if the get quota buffer contains a
    00552     valid, properly formed list, otherwise STATUS_QUOTA_LIST_INCONSISTENT.
    00553
    00554 --*/
    00555
    00556 {
    00557
    00558 #define GET_OFFSET_LENGTH( CurrentSid, SidBase ) ( (ULONG) ((PCHAR) CurrentSid - (PCHAR) SidBase) )
    00559
    00560     LONG tempLength;
    00561     LONG entrySize;
    00562     PFILE_GET_QUOTA_INFORMATION sids;
    00563
    00564     PAGED_CODE();
    00565
    00566     //
    00567     // Walk the buffer and ensure that its format is valid.  That is, ensure
    00568     // that it does not walk off the end of the buffer, is not recursive, etc.
    00569     //
    00570
    00571     sids = QuotaBuffer;
    00572     tempLength = QuotaLength;
    00573
    00574     for (;;) {
    00575
    00576         //
    00577         // Ensure that the current entry is valid.
    00578         //
    00579
    00580         if ((tempLength < (LONG) (FIELD_OFFSET(FILE_GET_QUOTA_INFORMATION, Sid.SubAuthority) +
    00581                                   sizeof (sids->Sid.SubAuthority))) ||
    00582             !RtlValidSid( &sids->Sid)) {
    00583
    00584             *ErrorOffset = GET_OFFSET_LENGTH( sids, QuotaBuffer );
    00585             return STATUS_QUOTA_LIST_INCONSISTENT;
    00586         }
    00587
    00588         //
    00589         // Get the size of the current entry in the buffer.
    00590         //
    00591
    00592         entrySize = FIELD_OFFSET( FILE_GET_QUOTA_INFORMATION, Sid ) + RtlLengthSid( (&sids->Sid) );
    00593
    00594         if (sids->NextEntryOffset) {
    00595
    00596             //
    00597             // There is another entry in the buffer and it must be longword
    00598             // aligned.  Ensure that the offset indicates that it is.  If it
    00599             // isn't, return an invalid parameter status.
    00600             //
    00601
    00602             if (entrySize > (LONG) sids->NextEntryOffset ||
    00603                 sids->NextEntryOffset & (sizeof( ULONG ) - 1)) {
    00604                 *ErrorOffset = GET_OFFSET_LENGTH( sids, QuotaBuffer );
    00605                 return STATUS_QUOTA_LIST_INCONSISTENT;
    00606
    00607             } else {
    00608
    00609                 //
    00610                 // There is another entry in the buffer, so account for the
    00611                 // size of the current entry in the length and get a pointer
    00612                 // to the next entry.
    00613                 //
    00614
    00615                 tempLength -= sids->NextEntryOffset;
    00616                 if (tempLength < 0) {
    00617                     *ErrorOffset = GET_OFFSET_LENGTH( sids, QuotaBuffer );
    00618                     return STATUS_QUOTA_LIST_INCONSISTENT;
    00619                 }
    00620                 sids = (PFILE_GET_QUOTA_INFORMATION) ((PCHAR) sids + sids->NextEntryOffset);
    00621             }
    00622
    00623         } else {
    00624
    00625             //
    00626             // There are no other entries in the buffer.  Simply account for
    00627             // the overall buffer length according to the size of the current
    00628             // entry and exit the loop.
    00629             //
    00630
    00631             tempLength -= entrySize;
    00632             break;
    00633         }
    00634     }
    00635
    00636     //
    00637     // All of the entries in the buffer have been processed.  Check to see
    00638     // whether the overall buffer length went negative.  If so, return an
    00639     // error.
    00640     //
    00641
    00642     if (tempLength < 0) {
    00643         *ErrorOffset = GET_OFFSET_LENGTH( sids, QuotaBuffer );
    00644         return STATUS_QUOTA_LIST_INCONSISTENT;
    00645     }
    00646
    00647     //
    00648     // The format of the get quota buffer was correct, so simply return a
    00649     // success status code.
    00650     //
    00651
    00652     return STATUS_SUCCESS;
    00653 }

VOID IopCloseFile | ( | IN PEPROCESS Process | OPTIONAL,
|  | IN PVOID | Object,
|  | IN ULONG | GrantedAccess,
|  | IN ULONG | ProcessHandleCount,
|  | IN ULONG | SystemHandleCount
| ) |

Definition at line 36 of file objsup.c.

References APC_LEVEL, _FILE_OBJECT::DeviceObject, _DEVICE_OBJECT::DriverObject, _FILE_OBJECT::Event, FALSE, _DRIVER_OBJECT::FastIoDispatch, _FAST_IO_DISPATCH::FastIoUnlockAll, _IO_STACK_LOCATION::FileObject, _FILE_OBJECT::Flags, _IRP::Flags, FO_DIRECT_DEVICE_OPEN, FO_HANDLE_CREATED, FO_SYNCHRONOUS_IO, IoCallDriver, IoFreeIrp(), IoGetAttachedDevice(), IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAcquireFastLock, IopAcquireFileObjectLock(), IopAllocateIrpMustSucceed(), IopDequeueThreadIrp, IopQueueThreadIrp, IopReleaseFileObjectLock, IopUpdateOtherOperationCount(), _IRP::IoStatus, IRP_CLOSE_OPERATION, IRP_MJ_CLEANUP, IRP_MJ_LOCK_CONTROL, IRP_MN_UNLOCK_ALL, IRP_SYNCHRONOUS_API, KeClearEvent, KeInitializeEvent, KeLowerIrql(), KeRaiseIrql(), KernelMode, KeWaitForSingleObject(), _FILE_OBJECT::LockOperation, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, ObReferenceObject, _IRP::Overlay, PAGED_CODE, PsGetCurrentProcess, PsGetCurrentThread, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, _IRP::Tail, _IRP::UserEvent, _IRP::UserIosb, UserRequest, and VOID().

Referenced by IopCreateObjectTypes(), and IopDeleteFile().

    00046                    :
    00047
    00048     This routine is invoked whenever a handle to a file is deleted.  If the
    00049     handle being deleted is the last handle to the file (the ProcessHandleCount
    00050     parameter is one), then all locks for the file owned by the specified
    00051     process must be released.
    00052
    00053     Likewise, if the SystemHandleCount is one then this is the last handle
    00054     for this for file object across all processes.  For this case, the file
    00055     system is notified so that it can perform any necessary cleanup on the
    00056     file.
    00057
    00058 Arguments:
    00059
    00060     Process - A pointer to the process that closed the handle.
    00061
    00062     Object - A pointer to the file object that the handle referenced.
    00063
    00064     GrantedAccess - Access that was granted to the object through the handle.
    00065
    00066     ProcessHandleCount - Count of handles outstanding to the object for the
    00067         process specified by the Process argument.  If the count is one
    00068         then this is the last handle to this file by that process.
    00069
    00070     SystemHandleCount - Count of handles outstanding to the object for the
    00071         entire system.  If the count is one then this is the last handle
    00072         to this file in the system.
    00073
    00074 Return Value:
    00075
    00076     None.
    00077
    00078 --*/
    00079
    00080 {
    00081     PIRP irp;
    00082     PIO_STACK_LOCATION irpSp;
    00083     PDEVICE_OBJECT deviceObject;
    00084     PFAST_IO_DISPATCH fastIoDispatch;
    00085     NTSTATUS status;
    00086     KEVENT event;
    00087     PFILE_OBJECT fileObject;
    00088     KIRQL irql;
    00089
    00090     UNREFERENCED_PARAMETER( Process );
    00091     UNREFERENCED_PARAMETER( GrantedAccess );
    00092
    00093     PAGED_CODE();
    00094
    00095     //
    00096     // If the handle count is not one then this is not the last close of
    00097     // this file for the specified process so there is nothing to do.
    00098     //
    00099
    00100     if (ProcessHandleCount != 1) {
    00101         return;
    00102     }
    00103
    00104     fileObject = (PFILE_OBJECT) Object;
    00105
    00106     if (fileObject->LockOperation && SystemHandleCount != 1) {
    00107
    00108         IO_STATUS_BLOCK localIoStatus;
    00109
    00110         //
    00111         // This is the last handle for the specified process and the process
    00112         // called the NtLockFile or NtUnlockFile system services at least once.
    00113         // Also, this is not the last handle for this file object system-wide
    00114         // so unlock all of the pending locks for this process.  Note that
    00115         // this check causes an optimization so that if this is the last
    00116         // system-wide handle to this file object the cleanup code will take
    00117         // care of releasing any locks on the file rather than having to
    00118         // send the file system two different packets to get them shut down.
    00119
    00120         //
    00121         // Get the address of the target device object and the Fast I/O dispatch
    00122         //
    00123
    00124         if (!(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    00125             deviceObject = IoGetRelatedDeviceObject( fileObject );
    00126         } else {
    00127             deviceObject = IoGetAttachedDevice( fileObject->DeviceObject );
    00128         }
    00129         fastIoDispatch = deviceObject->DriverObject->FastIoDispatch;
    00130
    00131         //
    00132         // If this file is open for synchronous I/O, wait until this thread
    00133         // owns it exclusively since there may still be a thread using it.
    00134         // This occurs when a system service owns the file because it owns
    00135         // the semaphore, but the I/O completion code has already dereferenced
    00136         // the file object itself.  Without waiting here for the same semaphore
    00137         // there would be a race condition in the service who owns it now. The
    00138         // service needs to be able to access the object w/o it going away after
    00139         // its wait for the file event is satisfied.
    00140         //
    00141
    00142         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    00143
    00144             BOOLEAN interrupted;
    00145
    00146             if (!IopAcquireFastLock( fileObject )) {
    00147                 (VOID) IopAcquireFileObjectLock( fileObject,
    00148                                                  KernelMode,
    00149                                                  FALSE,
    00150                                                  &interrupted );
    00151             }
    00152         }
    00153
    00154         //
    00155         // Turbo unlock support.  If the fast Io Dispatch specifies a fast lock
    00156         // routine then we'll first try and calling it with the specified lock
    00157         // parameters.  If this is all successful then we do not need to do
    00158         // the Irp based unlock all call.
    00159         //
    00160
    00161         if (fastIoDispatch &&
    00162             fastIoDispatch->FastIoUnlockAll &&
    00163             fastIoDispatch->FastIoUnlockAll( fileObject,
    00164                                              PsGetCurrentProcess(),
    00165                                              &localIoStatus,
    00166                                              deviceObject )) {
    00167
    00168             NOTHING;
    00169
    00170         } else {
    00171
    00172             //
    00173             // Initialize the local event that will be used to synchronize access
    00174             // to the driver completing this I/O operation.
    00175             //
    00176
    00177             KeInitializeEvent( &event, SynchronizationEvent, FALSE );
    00178
    00179             //
    00180             // Reset the event in the file object.
    00181             //
    00182
    00183             KeClearEvent( &fileObject->Event );
    00184
    00185             //
    00186             // Allocate and initialize the I/O Request Packet (IRP) for this
    00187             // operation.
    00188             //
    00189
    00190             irp = IopAllocateIrpMustSucceed( deviceObject->StackSize );
    00191             irp->Tail.Overlay.OriginalFileObject = fileObject;
    00192             irp->Tail.Overlay.Thread = PsGetCurrentThread();
    00193             irp->RequestorMode = KernelMode;
    00194
    00195             //
    00196             // Fill in the service independent parameters in the IRP.
    00197             //
    00198
    00199             irp->UserEvent = &event;
    00200             irp->UserIosb = &irp->IoStatus;
    00201             irp->Flags = IRP_SYNCHRONOUS_API;
    00202             irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    00203
    00204             //
    00205             // Get a pointer to the stack location for the first driver.  This will
    00206             // be used to pass the original function codes and parameters.  No
    00207             // function-specific parameters are required for this operation.
    00208             //
    00209
    00210             irpSp = IoGetNextIrpStackLocation( irp );
    00211             irpSp->MajorFunction = IRP_MJ_LOCK_CONTROL;
    00212             irpSp->MinorFunction = IRP_MN_UNLOCK_ALL;
    00213             irpSp->FileObject = fileObject;
    00214
    00215             //
    00216             //  Reference the fileobject again for the IRP (cleared on completion)
    00217             //
    00218
    00219             ObReferenceObject( fileObject );
    00220
    00221             //
    00222             // Insert the packet at the head of the IRP list for the thread.
    00223             //
    00224
    00225             IopQueueThreadIrp( irp );
    00226
    00227             //
    00228             // Invoke the driver at its appropriate dispatch entry with the IRP.
    00229             //
    00230
    00231             status = IoCallDriver( deviceObject, irp );
    00232
    00233             //
    00234             // If no error was incurred, wait for the I/O operation to complete.
    00235             //
    00236
    00237             if (status == STATUS_PENDING) {
    00238                 (VOID) KeWaitForSingleObject( &event,
    00239                                               UserRequest,
    00240                                               KernelMode,
    00241                                               FALSE,
    00242                                               (PLARGE_INTEGER) NULL );
    00243             }
    00244         }
    00245
    00246         //
    00247         // If this operation was a synchronous I/O operation, release the
    00248         // semaphore so that the file can be used by other threads.
    00249         //
    00250
    00251         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    00252             IopReleaseFileObjectLock( fileObject );
    00253         }
    00254     }
    00255
    00256     if (SystemHandleCount == 1) {
    00257
    00258         //
    00259         // The last handle to this file object for all of the processes in the
    00260         // system has just been closed, so invoke the driver's "cleanup" handler
    00261         // for this file.  This is the file system's opportunity to remove any
    00262         // share access information for the file, to indicate that if the file
    00263         // is opened for a caching operation and this is the last file object
    00264         // to the file, then it can do whatever it needs with memory management
    00265         // to cleanup any information.
    00266         //
    00267         // Begin by getting the address of the target device object.
    00268         //
    00269
    00270         if (!(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    00271             deviceObject = IoGetRelatedDeviceObject( fileObject );
    00272         } else {
    00273             deviceObject = IoGetAttachedDevice( fileObject->DeviceObject );
    00274         }
    00275
    00276         //
    00277         // Ensure that the I/O system believes that this file has a handle
    00278         // associated with it in case it doesn't actually get one from the
    00279         // Object Manager.  This is done because sometimes the Object Manager
    00280         // actually creates a handle, but the I/O system never finds out
    00281         // about it so it attempts to send two cleanups for the same file.
    00282         //
    00283
    00284         fileObject->Flags |= FO_HANDLE_CREATED;
    00285
    00286         //
    00287         // If this file is open for synchronous I/O, wait until this thread
    00288         // owns it exclusively since there may still be a thread using it.
    00289         // This occurs when a system service owns the file because it owns
    00290         // the semaphore, but the I/O completion code has already dereferenced
    00291         // the file object itself.  Without waiting here for the same semaphore
    00292         // there would be a race condition in the service who owns it now. The
    00293         // service needs to be able to access the object w/o it going away after
    00294         // its wait for the file event is satisfied.
    00295         //
    00296
    00297         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    00298
    00299             BOOLEAN interrupted;
    00300
    00301             if (!IopAcquireFastLock( fileObject )) {
    00302                 (VOID) IopAcquireFileObjectLock( fileObject,
    00303                                                  KernelMode,
    00304                                                  FALSE,
    00305                                                  &interrupted );
    00306             }
    00307         }
    00308
    00309         //
    00310         // Initialize the local event that will be used to synchronize access
    00311         // to the driver completing this I/O operation.
    00312         //
    00313
    00314         KeInitializeEvent( &event, SynchronizationEvent, FALSE );
    00315
    00316         //
    00317         // Reset the event in the file object.
    00318         //
    00319
    00320         KeClearEvent( &fileObject->Event );
    00321
    00322         //
    00323         // Allocate and initialize the I/O Request Packet (IRP) for this
    00324         // operation.
    00325         //
    00326
    00327         irp = IopAllocateIrpMustSucceed( deviceObject->StackSize );
    00328         irp->Tail.Overlay.OriginalFileObject = fileObject;
    00329         irp->Tail.Overlay.Thread = PsGetCurrentThread();
    00330         irp->RequestorMode = KernelMode;
    00331
    00332         //
    00333         // Fill in the service independent parameters in the IRP.
    00334         //
    00335
    00336         irp->UserEvent = &event;
    00337         irp->UserIosb = &irp->IoStatus;
    00338         irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    00339         irp->Flags = IRP_SYNCHRONOUS_API | IRP_CLOSE_OPERATION;
    00340
    00341         //
    00342         // Get a pointer to the stack location for the first driver.  This will
    00343         // be used to pass the original function codes and parameters.  No
    00344         // function-specific parameters are required for this operation.
    00345         //
    00346
    00347         irpSp = IoGetNextIrpStackLocation( irp );
    00348         irpSp->MajorFunction = IRP_MJ_CLEANUP;
    00349         irpSp->FileObject = fileObject;
    00350
    00351         //
    00352         // Insert the packet at the head of the IRP list for the thread.
    00353         //
    00354
    00355         IopQueueThreadIrp( irp );
    00356
    00357         //
    00358         // Update the operation count statistic for the current process for
    00359         // operations other than read and write.
    00360         //
    00361
    00362         IopUpdateOtherOperationCount();
    00363
    00364         //
    00365         // Invoke the driver at its appropriate dispatch entry with the IRP.
    00366         //
    00367
    00368         status = IoCallDriver( deviceObject, irp );
    00369
    00370         //
    00371         // If no error was incurred, wait for the I/O operation to complete.
    00372         //
    00373
    00374         if (status == STATUS_PENDING) {
    00375             (VOID) KeWaitForSingleObject( &event,
    00376                                           UserRequest,
    00377                                           KernelMode,
    00378                                           FALSE,
    00379                                           (PLARGE_INTEGER) NULL );
    00380         }
    00381
    00382         //
    00383         // The following code tears down the IRP by hand since it may not
    00384         // either be possible to it to be completed (because this code was
    00385         // invoked as APC_LEVEL in the first place - or because the reference
    00386         // count on the object cannot be incremented due to this routine
    00387         // being invoked by the delete file procedure below).  Cleanup IRPs
    00388         // therefore use close sematics (the close operation flag is set
    00389         // in the IRP) so that the I/O complete request routine itself sets
    00390         // the event to the Signaled state.
    00391         //
    00392
    00393         KeRaiseIrql( APC_LEVEL, &irql );
    00394         IopDequeueThreadIrp( irp );
    00395         KeLowerIrql( irql );
    00396
    00397         //
    00398         // Also, free the IRP.
    00399         //
    00400
    00401         IoFreeIrp( irp );
    00402
    00403         //
    00404         // If this operation was a synchronous I/O operation, release the
    00405         // semaphore so that the file can be used by other threads.
    00406         //
    00407
    00408         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    00409             IopReleaseFileObjectLock( fileObject );
    00410         }
    00411     }
    00412
    00413     return;
    00414 }

VOID IopCompletePageWrite | ( | IN PKAPC | Apc,
|  | IN PKNORMAL_ROUTINE * | NormalRoutine,
|  | IN PVOID * | NormalContext,
|  | IN PVOID * | SystemArgument1,
|  | IN PVOID * | SystemArgument2
| ) |

Definition at line 919 of file internal.c.

References IoFreeIrp(), _IRP::IoStatus, NT_ERROR, _IRP::Overlay, _IRP::PendingReturned, and _IRP::UserIosb.

    00929                    :
    00930
    00931     This routine executes as a special kernel APC routine in the context of
    00932     the Modified Page Writer (MPW) system thread when an out-page operation
    00933     has completed.
    00934
    00935     This routine performs the following tasks:
    00936
    00937         o   The I/O status is copied.
    00938
    00939         o   The Modified Page Writer's APC routine is invoked.
    00940
    00941 Arguments:
    00942
    00943     Apc - Supplies a pointer to kernel APC structure.
    00944
    00945     NormalRoutine - Supplies a pointer to a pointer to the normal function
    00946         that was specified when the APC was initialized.
    00947
    00948     NormalContext - Supplies a pointer to a pointer to an arbitrary data
    00949         structure that was specified when the APC was initialized.
    00950
    00951     SystemArgument1 - Supplies a pointer to an argument that contains an
    00952         argument that is unused by this routine.
    00953
    00954     SystemArgument2 - Supplies a pointer to an argument that contains an
    00955         argument that is unused by this routine.
    00956
    00957 Return Value:
    00958
    00959     None.
    00960
    00961 --*/
    00962
    00963 {
    00964     PIRP irp;
    00965     PIO_APC_ROUTINE apcRoutine;
    00966     PVOID apcContext;
    00967     PIO_STATUS_BLOCK ioStatus;
    00968
    00969     UNREFERENCED_PARAMETER( NormalRoutine );
    00970     UNREFERENCED_PARAMETER( NormalContext );
    00971     UNREFERENCED_PARAMETER( SystemArgument1 );
    00972     UNREFERENCED_PARAMETER( SystemArgument2 );
    00973
    00974     //
    00975     // Begin by getting the address of the I/O Request Packet from the APC.
    00976     //
    00977
    00978     irp = CONTAINING_RECORD( Apc, IRP, Tail.Apc );
    00979
    00980     //
    00981     // If this I/O operation did not complete successfully through the
    00982     // dispatch routine of the driver, then drop everything on the floor
    00983     // now and return to the original call point in the MPW.
    00984     //
    00985
    00986     if (!irp->PendingReturned && NT_ERROR( irp->IoStatus.Status )) {
    00987         IoFreeIrp( irp );
    00988         return;
    00989     }
    00990
    00991     //
    00992     // Copy the I/O status from the IRP into the caller's I/O status block.
    00993     //
    00994
    00995     *irp->UserIosb = irp->IoStatus;
    00996
    00997     //
    00998     // Copy the pertinent information from the I/O Request Packet into locals
    00999     // and free it.
    01000     //
    01001
    01002     apcRoutine = irp->Overlay.AsynchronousParameters.UserApcRoutine;
    01003     apcContext = irp->Overlay.AsynchronousParameters.UserApcContext;
    01004     ioStatus = irp->UserIosb;
    01005
    01006     IoFreeIrp( irp );
    01007
    01008     //
    01009     // Finally, invoke the MPW's APC routine.
    01010     //
    01011
    01012     apcRoutine( apcContext, ioStatus, 0 );
    01013
    01014     return;
    01015 }

VOID IopCompleteRequest | ( | IN PKAPC | Apc,
|  | IN PKNORMAL_ROUTINE * | NormalRoutine,
|  | IN PVOID * | NormalContext,
|  | IN PVOID * | SystemArgument1,
|  | IN PVOID * | SystemArgument2
| ) |

Definition at line 1019 of file internal.c.

References ASSERT, _IRP::AssociatedIrp, _FILE_OBJECT::CompletionContext, CurrentApcEnvironment, _FILE_OBJECT::Event, ExFreePool(), FALSE, _FILE_OBJECT::FinalStatus, _FILE_OBJECT::Flags, _IRP::Flags, FO_SYNCHRONOUS_IO, IoFreeIrp(), IoFreeMdl(), IopCompletionPacketIrp, IopDequeueThreadIrp, IopDoNameTransmogrify(), IopExceptionFilter(), IopUpdateOtherTransferCount(), IopUpdateReadTransferCount(), IopUpdateWriteTransferCount(), IopUserCompletion(), IopUserRundown(), _IRP::IoStatus, IOVP_COMPLETE_REQUEST, IRP_BUFFERED_IO, IRP_CREATE_OPERATION, IRP_DEALLOCATE_BUFFER, IRP_INPUT_OPERATION, IRP_OB_QUERY_NAME, IRP_READ_OPERATION, IRP_RETRY_IO_COMPLETION, IRP_SYNCHRONOUS_API, IRP_WRITE_OPERATION, KeInitializeApc(), KeInsertQueue(), KeInsertQueueApc(), KeSetEvent(), _IO_COMPLETION_CONTEXT::Key, _IRP::MdlAddress, MEMORY_BARRIER, _MDL::Next, NT_ERROR, NTSTATUS(), NULL, ObDereferenceObject, _IRP::Overlay, _IRP::PendingReturned, PKNORMAL_ROUTINE, PKRUNDOWN_ROUTINE, _IO_COMPLETION_CONTEXT::Port, PsGetCurrentThread, _IRP::RequestorMode, SynchronousIo, _IRP::Tail, _ETHREAD::Tcb, TRUE, _IRP::UserBuffer, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IopAbortRequest(), IopSynchronousServiceTail(), IoRetryIrpCompletions(), NtQueryInformationFile(), and NtSetInformationFile().

    01029                    :
    01030
    01031     This routine executes as a special kernel APC routine in the context of
    01032     the thread which originally requested the I/O operation which is now
    01033     being completed.
    01034
    01035     This routine performs the following tasks:
    01036
    01037         o   A check is made to determine whether the specified request ended
    01038             with an error status.  If so, and the error code qualifies as one
    01039             which should be reported to an error port, then an error port is
    01040             looked for in the thread/process.   If one exists, then this routine
    01041             will attempt to set up an LPC to it.  Otherwise, it will attempt to
    01042             set up an LPC to the system error port.
    01043
    01044         o   Copy buffers.
    01045
    01046         o   Free MDLs.
    01047
    01048         o   Copy I/O status.
    01049
    01050         o   Set event, if any and dereference if appropriate.
    01051
    01052         o   Dequeue the IRP from the thread queue as pending I/O request.
    01053
    01054         o   Queue APC to thread, if any.
    01055
    01056         o   If no APC is to be queued, then free the packet now.
    01057
    01058
    01059 Arguments:
    01060
    01061     Apc - Supplies a pointer to kernel APC structure.
    01062
    01063     NormalRoutine - Supplies a pointer to a pointer to the normal function
    01064         that was specified when the APC was initialied.
    01065
    01066     NormalContext - Supplies a pointer to a pointer to an arbitrary data
    01067         structure that was specified when the APC was initialized.
    01068
    01069     SystemArgument1 - Supplies a pointer to an argument that contains the
    01070         address of the original file object for this I/O operation.
    01071
    01072     SystemArgument2 - Supplies a pointer to an argument that contains an
    01073         argument that is used by this routine only in the case of STATUS_REPARSE.
    01074
    01075 Return Value:
    01076
    01077     None.
    01078
    01079 --*/
    01080 {
    01081 #define SynchronousIo( Irp, FileObject ) (  \
    01082     (Irp->Flags & IRP_SYNCHRONOUS_API) ||   \
    01083     (FileObject == NULL ? 0 : FileObject->Flags & FO_SYNCHRONOUS_IO) )
    01084
    01085     PIRP irp;
    01086     PMDL mdl, nextMdl;
    01087     PETHREAD thread;
    01088     PFILE_OBJECT fileObject;
    01089     NTSTATUS    status;
    01090
    01091     UNREFERENCED_PARAMETER( NormalRoutine );
    01092     UNREFERENCED_PARAMETER( NormalContext );
    01093
    01094     //
    01095     // Begin by getting the address of the I/O Request Packet.  Also, get
    01096     // the address of the current thread and the address of the original file
    01097     // object for this I/O operation.
    01098     //
    01099
    01100     irp = CONTAINING_RECORD( Apc, IRP, Tail.Apc );
    01101     thread = PsGetCurrentThread();
    01102     fileObject = (PFILE_OBJECT) *SystemArgument1;
    01103
    01104     IOVP_COMPLETE_REQUEST(Apc, SystemArgument1, SystemArgument2);
    01105
    01106     //
    01107     // Ensure that the packet is not being completed with a minus one.  This
    01108     // is apparently a common problem in some drivers, and has no meaning
    01109     // as a status code.
    01110     //
    01111
    01112     ASSERT( irp->IoStatus.Status != 0xffffffff );
    01113
    01114     //
    01115     // See if we need to do the name transmogrify work.
    01116     //
    01117
    01118     if ( *SystemArgument2 != NULL ) {
    01119
    01120         PREPARSE_DATA_BUFFER reparseBuffer = NULL;
    01121
    01122         //
    01123         // The IO_REPARSE_TAG_MOUNT_POINT tag needs attention.
    01124         //
    01125
    01126         if ( irp->IoStatus.Status == STATUS_REPARSE &&
    01127              irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT ) {
    01128
    01129             reparseBuffer = (PREPARSE_DATA_BUFFER) *SystemArgument2;
    01130
    01131             ASSERT( reparseBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT );
    01132             ASSERT( reparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
    01133             ASSERT( reparseBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
    01134
    01135             IopDoNameTransmogrify( irp,
    01136                                    fileObject,
    01137                                    reparseBuffer );
    01138         }
    01139     }
    01140
    01141     //
    01142     // Check to see whether there is any data in a system buffer which needs
    01143     // to be copied to the caller's buffer.  If so, copy the data and then
    01144     // free the system buffer if necessary.
    01145     //
    01146
    01147     if (irp->Flags & IRP_BUFFERED_IO) {
    01148
    01149         //
    01150         // Copy the data if this was an input operation.  Note that no copy
    01151         // is performed if the status indicates that a verify operation is
    01152         // required, or if the final status was an error-level severity.
    01153         //
    01154
    01155         if (irp->Flags & IRP_INPUT_OPERATION  &&
    01156             irp->IoStatus.Status != STATUS_VERIFY_REQUIRED &&
    01157             !NT_ERROR( irp->IoStatus.Status )) {
    01158
    01159             //
    01160             // Copy the information from the system buffer to the caller's
    01161             // buffer.  This is done with an exception handler in case
    01162             // the operation fails because the caller's address space
    01163             // has gone away, or it's protection has been changed while
    01164             // the service was executing.
    01165             //
    01166
    01167             try {
    01168                 RtlCopyMemory( irp->UserBuffer,
    01169                                irp->AssociatedIrp.SystemBuffer,
    01170                                irp->IoStatus.Information );
    01171             } except(IopExceptionFilter(GetExceptionInformation(), &status)) {
    01172
    01173                 //
    01174                 // An exception occurred while attempting to copy the
    01175                 // system buffer contents to the caller's buffer.  Set
    01176                 // a new I/O completion status.
    01177                 // If the status is a special one set by Mm then we need to
    01178                 // return here and the operation will be retried in
    01179                 // IoRetryIrpCompletions.
    01180                 //
    01181
    01182                 if (status == STATUS_MULTIPLE_FAULT_VIOLATION) {
    01183                     irp->Tail.Overlay.OriginalFileObject = fileObject;  /* Wiped out by APC  overlay */
    01184                     irp->Flags |= IRP_RETRY_IO_COMPLETION;
    01185                     return;
    01186                 }
    01187                 irp->IoStatus.Status = GetExceptionCode();
    01188             }
    01189         }
    01190
    01191         //
    01192         // Free the buffer if needed.
    01193         //
    01194
    01195         if (irp->Flags & IRP_DEALLOCATE_BUFFER) {
    01196             ExFreePool( irp->AssociatedIrp.SystemBuffer );
    01197         }
    01198     }
    01199
    01200     irp->Flags &= ~(IRP_DEALLOCATE_BUFFER|IRP_BUFFERED_IO);
    01201
    01202     //
    01203     // If there is an MDL (or MDLs) associated with this I/O request,
    01204     // Free it (them) here.  This is accomplished by walking the MDL list
    01205     // hanging off of the IRP and deallocating each MDL encountered.
    01206     //
    01207
    01208     if (irp->MdlAddress) {
    01209         for (mdl = irp->MdlAddress; mdl != NULL; mdl = nextMdl) {
    01210             nextMdl = mdl->Next;
    01211             IoFreeMdl( mdl );
    01212         }
    01213     }
    01214
    01215     irp->MdlAddress = NULL;
    01216
    01217     //
    01218     // Check to see whether or not the I/O operation actually completed.  If
    01219     // it did, then proceed normally.  Otherwise, cleanup everything and get
    01220     // out of here.
    01221     //
    01222
    01223     if (!NT_ERROR( irp->IoStatus.Status ) ||
    01224         (NT_ERROR( irp->IoStatus.Status ) &&
    01225         irp->PendingReturned &&
    01226         !SynchronousIo( irp, fileObject ))) {
    01227
    01228         PVOID port = NULL;
    01229         PVOID key;
    01230         BOOLEAN createOperation = FALSE;
    01231
    01232         //
    01233         // If there is an I/O completion port object associated w/this request,
    01234         // save it here so that the file object can be dereferenced.
    01235         //
    01236
    01237         if (fileObject && fileObject->CompletionContext) {
    01238             port = fileObject->CompletionContext->Port;
    01239             key = fileObject->CompletionContext->Key;
    01240         }
    01241
    01242         //
    01243         // Copy the I/O status from the IRP into the caller's I/O status
    01244         // block. This is done using an exception handler in case the caller's
    01245         // virtual address space for the I/O status block was deleted or
    01246         // its protection was changed to readonly.  Note that if the I/O
    01247         // status block cannot be written, the error is simply ignored since
    01248         // there is no way to tell the caller that something went wrong.
    01249         // This is, of course, by definition, since the I/O status block
    01250         // is where the caller will attempt to look for errors in the first
    01251         // place!
    01252         //
    01253
    01254         try {
    01255
    01256             //
    01257             // Since HasOverlappedIoCompleted and GetOverlappedResult only
    01258             // look at the Status field of the UserIosb to determine if the
    01259             // IRP has completed, the Information field must be written
    01260             // before the Status field.
    01261             //
    01262
    01263 #if defined(_M_ALPHA) && !defined(NT_UP)
    01264 #define MEMORY_BARRIER()    __MB()
    01265 #else
    01266 #define MEMORY_BARRIER()
    01267 #endif
    01268
    01269 #if defined(_WIN64)
    01270             PIO_STATUS_BLOCK32    UserIosb32;
    01271
    01272             //
    01273             // If the caller passes a 32 bit IOSB the ApcRoutine has the LSB set to 1
    01274             //
    01275             if ((ULONG_PTR)(irp->Overlay.AsynchronousParameters.UserApcRoutine) & 1) {
    01276                 UserIosb32 = (PIO_STATUS_BLOCK32)irp->UserIosb;
    01277
    01278                 UserIosb32->Information = (ULONG)irp->IoStatus.Information;
    01279                 MEMORY_BARRIER();
    01280                 UserIosb32->Status = (NTSTATUS)irp->IoStatus.Status;
    01281             } else {
    01282                 irp->UserIosb->Information = irp->IoStatus.Information;
    01283                 MEMORY_BARRIER();
    01284                 irp->UserIosb->Status = irp->IoStatus.Status;
    01285             }
    01286 #else
    01287             irp->UserIosb->Information = irp->IoStatus.Information;
    01288             MEMORY_BARRIER();
    01289             irp->UserIosb->Status = irp->IoStatus.Status;
    01290 #endif  /*_WIN64 */
    01291
    01292         } except(IopExceptionFilter(GetExceptionInformation(), &status)) {
    01293
    01294             //
    01295             // An exception was incurred attempting to write the caller's
    01296             // I/O status block.  Simply continue executing as if nothing
    01297             // ever happened since nothing can be done about it anyway.
    01298             // If the status is a multiple fault status, this is a special
    01299             // status sent by the Memory manager. Mark the IRP and return from
    01300             // this routine. Mm will call us back later and we will retry this
    01301             // operation (IoRetryIrpCompletions)
    01302             //
    01303             if (status == STATUS_MULTIPLE_FAULT_VIOLATION) {
    01304                 irp->Tail.Overlay.OriginalFileObject = fileObject;  /* Wiped out by APC  overlay */
    01305                 irp->Flags |= IRP_RETRY_IO_COMPLETION;
    01306                 return;
    01307             }
    01308         }
    01309
    01310
    01311         //
    01312         // Determine whether the caller supplied an event that needs to be set
    01313         // to the Signaled state.  If so, then set it; otherwise, set the event
    01314         // in the file object to the Signaled state.
    01315         //
    01316         // It is possible for the event to have been specified as a PKEVENT if
    01317         // this was an I/O operation hand-built for an FSP or an FSD, or
    01318         // some other types of operations such as synchronous I/O APIs.  In
    01319         // any of these cases, the event was not referenced since it is not an
    01320         // object manager event, so it should not be dereferenced.
    01321         //
    01322         // Also, it is possible for there not to be a file object for this IRP.
    01323         // This occurs when an FSP is doing I/O operations to a device driver on
    01324         // behalf of a process doing I/O to a file.  The file object cannot be
    01325         // dereferenced if this is the case.  If this operation was a create
    01326         // operation then the object should not be dereferenced either.  This
    01327         // is because the reference count must be one or it will go away for
    01328         // the caller (not much point in making an object that just got created
    01329         // go away).
    01330         //
    01331
    01332         if (irp->UserEvent) {
    01333             (VOID) KeSetEvent( irp->UserEvent, 0, FALSE );
    01334             if (fileObject) {
    01335                 if (!(irp->Flags & IRP_SYNCHRONOUS_API)) {
    01336                     ObDereferenceObject( irp->UserEvent );
    01337                 }
    01338                 if (fileObject->Flags & FO_SYNCHRONOUS_IO && !(irp->Flags & IRP_OB_QUERY_NAME)) {
    01339                     (VOID) KeSetEvent( &fileObject->Event, 0, FALSE );
    01340                     fileObject->FinalStatus = irp->IoStatus.Status;
    01341                 }
    01342                 if (irp->Flags & IRP_CREATE_OPERATION) {
    01343                     createOperation = TRUE;
    01344                     irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    01345                 }
    01346             }
    01347         } else if (fileObject) {
    01348             (VOID) KeSetEvent( &fileObject->Event, 0, FALSE );
    01349             fileObject->FinalStatus = irp->IoStatus.Status;
    01350             if (irp->Flags & IRP_CREATE_OPERATION) {
    01351                 createOperation = TRUE;
    01352                 irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    01353             }
    01354         }
    01355
    01356         //
    01357         // If this is normal I/O, update the transfer count for this process.
    01358         //
    01359
    01360         if (!(irp->Flags & IRP_CREATE_OPERATION)) {
    01361             if (irp->Flags & IRP_READ_OPERATION) {
    01362                 IopUpdateReadTransferCount( (ULONG) irp->IoStatus.Information );
    01363             } else if (irp->Flags & IRP_WRITE_OPERATION) {
    01364                 IopUpdateWriteTransferCount( (ULONG) irp->IoStatus.Information );
    01365             } else {
    01366                 //
    01367                 // If the information field contains a pointer then skip the update.
    01368                 // Some PNP IRPs contain this.
    01369                 //
    01370                 if (!((ULONG) irp->IoStatus.Information & 0x80000000)) {
    01371                     IopUpdateOtherTransferCount( (ULONG) irp->IoStatus.Information );
    01372                 }
    01373             }
    01374         }
    01375
    01376         //
    01377         // Dequeue the packet from the thread's pending I/O request list.
    01378         //
    01379
    01380         IopDequeueThreadIrp( irp );
    01381
    01382         //
    01383         // If the caller requested an APC, queue it to the thread.  If not, then
    01384         // simply free the packet now.
    01385         //
    01386
    01387 #ifdef  _WIN64
    01388         //
    01389         // For 64 bit systems clear the LSB field of the ApcRoutine that indicates whether
    01390         // the IOSB is a 32 bit IOSB or a 64 bit IOSB.
    01391         //
    01392         irp->Overlay.AsynchronousParameters.UserApcRoutine =
    01393           (PIO_APC_ROUTINE)((LONG_PTR)(irp->Overlay.AsynchronousParameters.UserApcRoutine) & ~1);
    01394 #endif
    01395
    01396         if (irp->Overlay.AsynchronousParameters.UserApcRoutine) {
    01397             KeInitializeApc( &irp->Tail.Apc,
    01398                              &thread->Tcb,
    01399                              CurrentApcEnvironment,
    01400                              IopUserCompletion,
    01401                              (PKRUNDOWN_ROUTINE) IopUserRundown,
    01402                              (PKNORMAL_ROUTINE) irp->Overlay.AsynchronousParameters.UserApcRoutine,
    01403                              irp->RequestorMode,
    01404                              irp->Overlay.AsynchronousParameters.UserApcContext );
    01405
    01406             KeInsertQueueApc( &irp->Tail.Apc,
    01407                               irp->UserIosb,
    01408                               NULL,
    01409                               2 );
    01410
    01411         } else if (port && irp->Overlay.AsynchronousParameters.UserApcContext) {
    01412
    01413             //
    01414             // If there is a completion context associated w/this I/O operation,
    01415             // send the message to the port. Tag completion packet as an Irp.
    01416             //
    01417
    01418             irp->Tail.CompletionKey = key;
    01419             irp->Tail.Overlay.PacketType = IopCompletionPacketIrp;
    01420
    01421             KeInsertQueue( (PKQUEUE) port,
    01422                            &irp->Tail.Overlay.ListEntry );
    01423
    01424         } else {
    01425
    01426             //
    01427             // Free the IRP now since it is no longer needed.
    01428             //
    01429
    01430             IoFreeIrp( irp );
    01431         }
    01432
    01433         if (fileObject && !createOperation) {
    01434
    01435             //
    01436             // Dereference the file object now.
    01437             //
    01438
    01439             ObDereferenceObject( fileObject );
    01440         }
    01441
    01442     } else {
    01443
    01444         if (irp->PendingReturned && fileObject) {
    01445
    01446             //
    01447             // This is an I/O operation that completed as an error for
    01448             // which a pending status was returned and the I/O operation
    01449             // is synchronous.  For this case, the I/O system is waiting
    01450             // on behalf of the caller.  If the reason that the I/O was
    01451             // synchronous is that the file object was opened for synchronous
    01452             // I/O, then the event associated with the file object is set
    01453             // to the signaled state.  If the I/O operation was synchronous
    01454             // because this is a synchronous API, then the event is set to
    01455             // the signaled state.
    01456             //
    01457             // Note also that the status must be returned for both types
    01458             // of synchronous I/O.  If this is a synchronous API, then the
    01459             // I/O system supplies its own status block so it can simply
    01460             // be written;  otherwise, the I/O system will obtain the final
    01461             // status from the file object itself.
    01462             //
    01463
    01464             if (irp->Flags & IRP_SYNCHRONOUS_API) {
    01465                 *irp->UserIosb = irp->IoStatus;
    01466                 if (irp->UserEvent) {
    01467                     (VOID) KeSetEvent( irp->UserEvent, 0, FALSE );
    01468                 } else {
    01469                     (VOID) KeSetEvent( &fileObject->Event, 0, FALSE );
    01470                 }
    01471             } else {
    01472                 fileObject->FinalStatus = irp->IoStatus.Status;
    01473                 (VOID) KeSetEvent( &fileObject->Event, 0, FALSE );
    01474             }
    01475         }
    01476
    01477         //
    01478         // The operation was incomplete.  Perform the general cleanup.  Note
    01479         // that everything is basically dropped on the floor without doing
    01480         // anything.  That is:
    01481         //
    01482         //     IoStatusBlock - Do nothing.
    01483         //     Event - Dereference without setting to Signaled state.
    01484         //     FileObject - Dereference without setting to Signaled state.
    01485         //     ApcRoutine - Do nothing.
    01486         //
    01487
    01488         if (fileObject) {
    01489             if (!(irp->Flags & IRP_CREATE_OPERATION)) {
    01490                 ObDereferenceObject( fileObject );
    01491             }
    01492         }
    01493
    01494         if (irp->UserEvent &&
    01495             fileObject &&
    01496             !(irp->Flags & IRP_SYNCHRONOUS_API)) {
    01497             ObDereferenceObject( irp->UserEvent );
    01498         }
    01499
    01500         IopDequeueThreadIrp( irp );
    01501         IoFreeIrp( irp );
    01502     }
    01503 }

VOID IopCompleteUnloadOrDelete | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN KIRQL | Irql
| ) |

Definition at line 657 of file internal.c.

References ASSERT, _DEVICE_OBJECT::AttachedDevice, DelayedWorkQueue, _DEVOBJ_EXTENSION::DeviceNode, _DRIVER_OBJECT::DeviceObject, _DEVICE_OBJECT::DeviceObjectExtension, DNF_REMOVE_PENDING_CLOSES, DOE_DELETE_PENDING, DOE_REMOVE_PENDING, DOE_REMOVE_PROCESSED, DOE_UNLOAD_PENDING, _LOAD_PACKET::DriverObject, DRVO_UNLOAD_INVOKED, _LOAD_PACKET::Event, Executive, ExFreePool(), ExInitializeWorkItem, ExQueueWorkItem(), _DEVOBJ_EXTENSION::ExtensionFlags, FALSE, _FAST_IO_DISPATCH::FastIoDetachDevice, _DRIVER_OBJECT::Flags, _DEVICE_NODE::Flags, IopChainDereferenceComplete(), IopDatabaseLock, IopGetDeviceAttachmentBase(), IopInsertRemoveDevice(), IopLoadUnloadDriver(), KeInitializeEvent, KernelMode, KeWaitForSingleObject(), LOAD_PACKET, _DEVICE_OBJECT::NextDevice, NULL, ObDereferenceObject, ObMakeTemporaryObject(), PDEVOBJ_EXTENSION, _DEVICE_OBJECT::ReferenceCount, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, TRUE, VOID(), and _LOAD_PACKET::WorkQueueItem.

Referenced by IoDeleteDevice(), IoDetachDevice(), and IopDecrementDeviceObjectRef().

    00664                    :
    00665
    00666     This routine is invoked when the reference count on a device object
    00667     transitions to a zero and the driver is mark for unload or device has
    00668     been marked for delete. This means that it may be possible to actually
    00669     unload the driver or delete the device object.  If all
    00670     of the devices have a reference count of zero, then the driver is
    00671     actually unloaded.  Note that in order to ensure that this routine is
    00672     not invoked twice, at the same time, on two different processors, the
    00673     I/O database spin lock is still held at this point.
    00674
    00675 Arguments:
    00676
    00677     DeviceObject - Supplies a pointer to one of the driver's device objects,
    00678         namely the one whose reference count just went to zero.
    00679
    00680     Irql - Specifies the IRQL of the processor at the time that the I/O
    00681         database lock was acquired.
    00682
    00683 Return Value:
    00684
    00685     None.
    00686
    00687 --*/
    00688
    00689 {
    00690     PDRIVER_OBJECT driverObject;
    00691     PDEVICE_OBJECT deviceObject;
    00692     PDEVICE_OBJECT baseDeviceObject;
    00693     PDEVICE_OBJECT attachedDeviceObject;
    00694     PDEVOBJ_EXTENSION deviceExtension;
    00695     PDEVICE_NODE deviceNode;
    00696
    00697     BOOLEAN unload = TRUE;
    00698
    00699     driverObject = DeviceObject->DriverObject;
    00700
    00701     if (DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_REMOVE_PENDING) {
    00702
    00703         //
    00704         // Run some tests to determine if it is an appropriate time to notify
    00705         // PnP that all file objects in the attachment chain have gone away.
    00706         //
    00707
    00708         baseDeviceObject = IopGetDeviceAttachmentBase( DeviceObject );
    00709         deviceExtension = baseDeviceObject->DeviceObjectExtension;
    00710         deviceNode = (PDEVICE_NODE)deviceExtension->DeviceNode;
    00711
    00712         ASSERT(deviceNode != NULL);
    00713
    00714         //
    00715         // baseDeviceObject is a PDO, this is a PnP stack.  See if
    00716         // an IRP_MN_REMOVE_DEVICE is pending.
    00717         //
    00718
    00719         ASSERT(deviceNode->Flags & DNF_REMOVE_PENDING_CLOSES);
    00720
    00721         //
    00722         // PnP wants to be notified as soon as all refcounts on all devices in
    00723         // this attachment chain go away.
    00724         //
    00725
    00726         attachedDeviceObject = baseDeviceObject;
    00727         while (attachedDeviceObject != NULL) {
    00728
    00729             if (attachedDeviceObject->ReferenceCount != 0) {
    00730
    00731                 //
    00732                 // At least one device object in the attachment chain has
    00733                 // an outstanding open.
    00734                 //
    00735
    00736                 ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00737
    00738                 return;
    00739             }
    00740             attachedDeviceObject = attachedDeviceObject->AttachedDevice;
    00741         }
    00742
    00743         //
    00744         // Now one more time changing DOE_REMOVE_PENDING to
    00745         // DOE_REMOVE_PROCESSED.
    00746         //
    00747
    00748         attachedDeviceObject = baseDeviceObject;
    00749         while (attachedDeviceObject != NULL) {
    00750
    00751             deviceExtension = attachedDeviceObject->DeviceObjectExtension;
    00752
    00753             deviceExtension->ExtensionFlags &= ~DOE_REMOVE_PENDING;
    00754             deviceExtension->ExtensionFlags |= DOE_REMOVE_PROCESSED;
    00755
    00756             attachedDeviceObject = attachedDeviceObject->AttachedDevice;
    00757         }
    00758
    00759         //
    00760         // It is time to give PnP the notification it was waiting for.  We have
    00761         // to release the spinlock before doing so.
    00762         //
    00763
    00764         ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00765
    00766         IopChainDereferenceComplete( baseDeviceObject );
    00767
    00768         return;
    00769     }
    00770
    00771     if (DeviceObject->DeviceObjectExtension->ExtensionFlags & DOE_DELETE_PENDING) {
    00772
    00773         if ((DeviceObject->DeviceObjectExtension->ExtensionFlags &
    00774             DOE_UNLOAD_PENDING) == 0 ||
    00775             driverObject->Flags & DRVO_UNLOAD_INVOKED) {
    00776
    00777             unload = FALSE;
    00778         }
    00779
    00780         //
    00781         // If another device is attached to this device, inform the former's
    00782         // driver that the device is being deleted.
    00783         //
    00784
    00785         if (DeviceObject->AttachedDevice) {
    00786             PFAST_IO_DISPATCH fastIoDispatch = DeviceObject->AttachedDevice->DriverObject->FastIoDispatch;
    00787             PDEVICE_OBJECT attachedDevice = DeviceObject->AttachedDevice;
    00788
    00789             //
    00790             // Increment the device reference count so the detach routine
    00791             // does not recurse back to here.
    00792             //
    00793
    00794             DeviceObject->ReferenceCount++;
    00795
    00796             ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00797
    00798             if (fastIoDispatch &&
    00799                 fastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET( FAST_IO_DISPATCH, FastIoDetachDevice ) &&
    00800                 fastIoDispatch->FastIoDetachDevice) {
    00801                 (fastIoDispatch->FastIoDetachDevice)( attachedDevice, DeviceObject );
    00802             }
    00803
    00804             ExAcquireSpinLock( &IopDatabaseLock, &Irql );
    00805
    00806             //
    00807             // Restore the reference count value.
    00808             //
    00809
    00810             DeviceObject->ReferenceCount--;
    00811
    00812             if (DeviceObject->AttachedDevice ||
    00813                 DeviceObject->ReferenceCount != 0) {
    00814
    00815
    00816                 ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00817                 return;
    00818             }
    00819         }
    00820
    00821         ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00822
    00823         //
    00824         // Deallocate the memory for the security descriptor that was allocated
    00825         // for this device object.
    00826         //
    00827
    00828         if (DeviceObject->SecurityDescriptor != (PSECURITY_DESCRIPTOR) NULL) {
    00829             ExFreePool( DeviceObject->SecurityDescriptor );
    00830         }
    00831
    00832         //
    00833         // Remove this device object from the driver object's list.
    00834         //
    00835
    00836         IopInsertRemoveDevice( DeviceObject->DriverObject, DeviceObject, FALSE );
    00837
    00838         //
    00839         // Finally, dereference the object so it is deleted.
    00840         //
    00841
    00842         ObDereferenceObject( DeviceObject );
    00843
    00844         //
    00845         // Return if the unload does not need to be done.
    00846         //
    00847
    00848         if (!unload) {
    00849             return;
    00850         }
    00851
    00852         //
    00853         // Reacquire the spin lock make sure the unload routine does has
    00854         // not been called.
    00855         //
    00856
    00857         ExAcquireSpinLock( &IopDatabaseLock, &Irql );
    00858
    00859         if (driverObject->Flags & DRVO_UNLOAD_INVOKED) {
    00860
    00861             //
    00862             // Some other thread is doing the unload, release the lock and return.
    00863             //
    00864
    00865             ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00866             return;
    00867         }
    00868     }
    00869
    00870     //
    00871     // Scan the list of device objects for this driver, looking for a
    00872     // non-zero reference count.  If any reference count is non-zero, then
    00873     // the driver may not be unloaded.
    00874     //
    00875
    00876     deviceObject = driverObject->DeviceObject;
    00877
    00878     while (deviceObject) {
    00879         if (deviceObject->ReferenceCount || deviceObject->AttachedDevice ||
    00880             deviceObject->DeviceObjectExtension->ExtensionFlags & (DOE_DELETE_PENDING | DOE_REMOVE_PENDING)) {
    00881             unload = FALSE;
    00882             break;
    00883         }
    00884         deviceObject = deviceObject->NextDevice;
    00885     }
    00886
    00887     if (unload) {
    00888         driverObject->Flags |= DRVO_UNLOAD_INVOKED;
    00889     }
    00890
    00891     ExReleaseSpinLock( &IopDatabaseLock, Irql );
    00892
    00893     //
    00894     // If the reference counts for all of the devices is zero, then this
    00895     // driver can now be unloaded.
    00896     //
    00897
    00898     if (unload) {
    00899         LOAD_PACKET loadPacket;
    00900
    00901         KeInitializeEvent( &loadPacket.Event, NotificationEvent, FALSE );
    00902         loadPacket.DriverObject = driverObject;
    00903         ExInitializeWorkItem( &loadPacket.WorkQueueItem,
    00904                               IopLoadUnloadDriver,
    00905                               &loadPacket );
    00906         ExQueueWorkItem( &loadPacket.WorkQueueItem, DelayedWorkQueue );
    00907         (VOID) KeWaitForSingleObject( &loadPacket.Event,
    00908                                       Executive,
    00909                                       KernelMode,
    00910                                       FALSE,
    00911                                       (PLARGE_INTEGER) NULL );
    00912
    00913         ObMakeTemporaryObject( driverObject );
    00914         ObDereferenceObject( driverObject );
    00915     }
    00916 }

BOOLEAN IopConfigureCrashDump | ( | IN HANDLE | HandlePagingFile | ) |

Definition at line 4746 of file dumpctl.c.

References DCB_DUMP_ENABLED, DCB_SUMMARY_ENABLED, DeviceUsageTypeDumpFile, DO_SYSTEM_BOOT_PARTITION, _DUMP_CONTROL_BLOCK::DumpFileSize, _DUMP_CONTROL_BLOCK::DumpStack, ExAllocatePoolWithTag, FALSE, _DEVICE_OBJECT::Flags, _DUMP_CONTROL_BLOCK::Flags, _DUMP_CONTROL_BLOCK::HeaderSize, IO_DUMP_MEMORY_BLOCK_PAGES, IoDebugPrint, IoFileObjectType, IoGetDumpStack(), IopCalculateRequiredDumpSpace(), IopCompleteDumpInitialization(), IopDumpControlBlock, IopFreeDCB(), IopInitializeDCB(), IopLogErrorEvent(), KernelMode, L, _DUMP_CONTROL_BLOCK::MemoryDescriptor, NonPagedPool, NT_SUCCESS, NULL, _PHYSICAL_MEMORY_DESCRIPTOR::NumberOfPages, ObDereferenceObject, ObReferenceObjectByHandle(), PAGE_SIZE, and TRUE.

Referenced by IoPageFileCreated().

    04751                    :
    04752
    04753     This routine configures the system for crash dump. The following things
    04754     are done:
    04755
    04756         1. Initialize the dump control block and init registry crashdump
    04757            parameters.
    04758
    04759         2. Configure either page or fast dump.
    04760
    04761         3. Complete dump file initialization.
    04762
    04763     This routine is called as each page file is created. A return value of
    04764     TRUE tells the caller (i.e., NtCreatePagingFiles, IoPageFileCreated)
    04765     that crash dump has been configured.
    04766
    04767
    04768 Arguments:
    04769
    04770        hPageFile - Handle to the paging file
    04771
    04772 Return Value:
    04773
    04774     TRUE - Configuration complete (or crash dump not enabled).
    04775
    04776     FALSE - Error, retry PageFile is not on boot partition.
    04777
    04778 --*/
    04779 {
    04780     ULONG           dwStatus;
    04781     PFILE_OBJECT    fileObject;
    04782     PDEVICE_OBJECT  deviceObject;
    04783
    04784     //
    04785     // Only Init DCB Once.
    04786     //
    04787
    04788     if (!IopDumpControlBlock) {
    04789         if (!IopInitializeDCB()) {
    04790             return TRUE;
    04791         }
    04792     }
    04793
    04794     //
    04795     // Return crash dump not enabled
    04796     //
    04797     if (!IopDumpControlBlock){
    04798         return TRUE;
    04799     }
    04800
    04801     //
    04802     //  Only autoreboot?
    04803     //
    04804
    04805     if ( !( IopDumpControlBlock->Flags & (DCB_DUMP_ENABLED | DCB_SUMMARY_ENABLED) ) ) {
    04806         return TRUE;
    04807     }
    04808
    04809     //
    04810     // Configure the paging file for crash dump.
    04811     //
    04812
    04813     IoDebugPrint((2,"[IoPageFileCreated]: Page file dump\n"));
    04814
    04815
    04816     dwStatus = ObReferenceObjectByHandle(
    04817                                         hPageFile,
    04818                                         0,
    04819                                         IoFileObjectType,
    04820                                         KernelMode,
    04821                                         (PVOID *) &fileObject,
    04822                                         NULL
    04823                                         );
    04824
    04825     if (!NT_SUCCESS( dwStatus )) {
    04826         IoDebugPrint((1,"[IoPageFileCreated]: ObReferenceObjectByHandle for Paging file failed status = %x\n",dwStatus));
    04827         goto error_return;
    04828     }
    04829
    04830     //
    04831     // Get a pointer to the device object for this file.  Note that it
    04832     // cannot go away, since there is an open handle to it, so it is
    04833     // OK to dereference it and then use it.
    04834     //
    04835
    04836     deviceObject = fileObject->DeviceObject;
    04837
    04838     ObDereferenceObject( fileObject );
    04839
    04840     //
    04841     // If this device object does not represents the boot partition return
    04842     // FALSE so MM will try again.
    04843     //
    04844
    04845     if ( ! (deviceObject->Flags & DO_SYSTEM_BOOT_PARTITION) ) {
    04846         return FALSE;
    04847     }
    04848
    04849     //
    04850     // Load paging file dump stack
    04851     //
    04852
    04853     dwStatus = IoGetDumpStack (L"dump_",
    04854                                &IopDumpControlBlock->DumpStack,
    04855                                DeviceUsageTypeDumpFile,
    04856                                FALSE);
    04857
    04858     if (!NT_SUCCESS(dwStatus)) {
    04859         IoDebugPrint((1, "IoPageFileCreated: Could not load dump stack status = %x\n",dwStatus) );
    04860         goto error_return;
    04861     }
    04862
    04863     IopDumpControlBlock->DumpStack->Init.CrashDump = TRUE;
    04864
    04865     IopDumpControlBlock->DumpStack->Init.MemoryBlock = ExAllocatePoolWithTag (
    04866                                                 NonPagedPool,
    04867                                                 IO_DUMP_MEMORY_BLOCK_PAGES * PAGE_SIZE,
    04868                                                 'pmuD'
    04869                                                 );
    04870
    04871     if (!IopDumpControlBlock->DumpStack->Init.MemoryBlock) {
    04872         dwStatus = STATUS_NO_MEMORY;
    04873         goto error_return;
    04874     }
    04875
    04876
    04877     //
    04878     // Calculate the amount of space required for the dump
    04879     //
    04880     IopDumpControlBlock->DumpFileSize =IopCalculateRequiredDumpSpace(
    04881                                                     IopDumpControlBlock->Flags,
    04882                                                     IopDumpControlBlock->HeaderSize,
    04883                                                     IopDumpControlBlock->MemoryDescriptor->NumberOfPages,
    04884                                                     IopDumpControlBlock->MemoryDescriptor->NumberOfPages
    04885                                                     );
    04886
    04887
    04888     //
    04889     // Complete dump initialization
    04890     //
    04891
    04892     dwStatus = IopCompleteDumpInitialization(hPageFile);
    04893
    04894 error_return:
    04895
    04896     //
    04897     // The BOOT partition paging file could not be configured.
    04898     //   1. Log an error message
    04899     //   2. Return TRUE so that MM does not try again
    04900     //
    04901
    04902     if (!NT_SUCCESS(dwStatus)) {
    04903         IoDebugPrint((1,"IopPageFileCreated: Page File dump init FAILED status = %x\n",dwStatus));
    04904
    04905         IopLogErrorEvent(0,3,STATUS_SUCCESS,IO_DUMP_PAGE_CONFIG_FAILED,0,NULL,0,NULL);
    04906
    04907         IopFreeDCB(FALSE);
    04908
    04909     }
    04910
    04911     return TRUE;
    04912 }

VOID IopConnectLinkTrackingPort | ( | IN PVOID | Parameter | ) |

Definition at line 1506 of file internal.c.

References _LINK_TRACKING_PACKET::Event, FALSE, _LINK_TRACKING_PACKET::FinalStatus, IopLinkTrackingServiceEvent, IopLinkTrackingServiceObject, KeReadStateEvent(), KernelMode, KeSetEvent(), L, LpcPortObjectType, MESSAGE_SIZE, NT_SUCCESS, NtClose(), NtConnectPort(), NTSTATUS(), NULL, ObReferenceObjectByHandle(), PAGED_CODE, PLINK_TRACKING_PACKET, RtlInitUnicodeString(), and TRUE.

Referenced by IopSendMessageToTrackService().

    01512                    :
    01513
    01514     This routine is invoked to connect to the user-mode link tracking service's
    01515     LPC port.  It makes a connection which establishes a handle to the port,
    01516     and then creates a referenced object pointer to the port.
    01517
    01518 Arguments:
    01519
    01520     Parameter - Pointer to the link tracking packet.
    01521
    01522 Return Value:
    01523
    01524     None.
    01525
    01526
    01527 --*/
    01528
    01529 {
    01530     #define MESSAGE_SIZE    ( (2 * sizeof( FILE_VOLUMEID_WITH_TYPE )) + \
    01531                             sizeof( FILE_OBJECTID_BUFFER ) +              \
    01532                             sizeof( GUID ) + \
    01533                             sizeof( NTSTATUS ) + \
    01534                             sizeof( ULONG ) )
    01535
    01536     PLINK_TRACKING_PACKET ltp;
    01537     HANDLE serviceHandle;
    01538     NTSTATUS status;
    01539
    01540     PAGED_CODE();
    01541     //
    01542     // Begin by getting a pointer to the link tracking packet.
    01543     //
    01544
    01545     ltp = (PLINK_TRACKING_PACKET) Parameter;
    01546
    01547
    01548     //
    01549     // Ensure that the port has not already been opened.
    01550     //
    01551
    01552     status = STATUS_SUCCESS;
    01553     if (!IopLinkTrackingServiceObject) {
    01554
    01555         UNICODE_STRING portName;
    01556         ULONG maxMessageLength;
    01557         SECURITY_QUALITY_OF_SERVICE dynamicQos;
    01558
    01559         if (KeReadStateEvent( IopLinkTrackingServiceEvent )) {
    01560
    01561             //
    01562             // Attempt to open a handle to the port.
    01563             //
    01564
    01565             //
    01566             // Set up the security quality of service parameters to use over the
    01567             // port.  Use the most efficient (least overhead) which is dynamic
    01568             // rather than static tracking.
    01569             //
    01570
    01571             dynamicQos.ImpersonationLevel = SecurityImpersonation;
    01572             dynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    01573             dynamicQos.EffectiveOnly = TRUE;
    01574
    01575             //
    01576             // Generate the string structure for describing the port.
    01577             //
    01578
    01579             RtlInitUnicodeString( &portName, L"\\Security\\TRKWKS_PORT" );
    01580
    01581             status = NtConnectPort( &serviceHandle,
    01582                                     &portName,
    01583                                     &dynamicQos,
    01584                                     (PPORT_VIEW) NULL,
    01585                                     (PREMOTE_PORT_VIEW) NULL,
    01586                                     &maxMessageLength,
    01587                                     (PVOID) NULL,
    01588                                     (PULONG) NULL );
    01589             if (NT_SUCCESS( status )) {
    01590                 if (maxMessageLength >= MESSAGE_SIZE) {
    01591                     status = ObReferenceObjectByHandle( serviceHandle,
    01592                                                         0,
    01593                                                         LpcPortObjectType,
    01594                                                         KernelMode,
    01595                                                         &IopLinkTrackingServiceObject,
    01596                                                         NULL );
    01597                     NtClose( serviceHandle );
    01598                 } else {
    01599                     NtClose( serviceHandle );
    01600                     status = STATUS_INVALID_PARAMETER;
    01601                 }
    01602             }
    01603
    01604         } else {
    01605
    01606             //
    01607             // The service has not been started so the port does not exist.
    01608             //
    01609
    01610             status = STATUS_OBJECT_NAME_NOT_FOUND;
    01611         }
    01612     }
    01613
    01614
    01615     //
    01616     // Return final status and wake the caller up.
    01617     //
    01618     ltp->FinalStatus = status;
    01619     KeSetEvent( &ltp->Event, 0, FALSE );
    01620 }

PSECURITY_DESCRIPTOR IopCreateDefaultDeviceSecurityDescriptor | ( | IN DEVICE_TYPE | DeviceType,
|  | IN ULONG | DeviceCharacteristics,
|  | IN BOOLEAN | DeviceHasName,
|  | IN PUCHAR | Buffer,
|  | OUT PACL * | AllocatedAcl,
|  | OUT PSECURITY_INFORMATION SecurityInformation | OPTIONAL
| ) |

Definition at line 12098 of file iosubs.c.

References ASSERT, Buffer, ExAllocatePoolWithTag, FALSE, NT_SUCCESS, NTSTATUS(), NULL, PagedPool, RtlCreateSecurityDescriptor(), RtlEqualSid(), RtlGetAce(), RtlSetDaclSecurityDescriptor(), SeAliasAdminsSid, SePublicDefaultUnrestrictedDacl, SePublicOpenUnrestrictedDacl, SeWorldSid, and TRUE.

Referenced by IoCreateDevice(), and IopChangeDeviceObjectFromRegistryProperties().

    12106 {
    12107     PSECURITY_DESCRIPTOR descriptor = (PSECURITY_DESCRIPTOR) Buffer;
    12108
    12109     NTSTATUS status;
    12110
    12111     if(ARGUMENT_PRESENT(SecurityInformation)) {
    12112         (*SecurityInformation) = 0;
    12113     }
    12114
    12115     *AllocatedAcl = NULL;
    12116
    12117     switch ( DeviceType ) {
    12118
    12119         case FILE_DEVICE_DISK_FILE_SYSTEM:
    12120         case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
    12121         case FILE_DEVICE_FILE_SYSTEM:
    12122         case FILE_DEVICE_TAPE_FILE_SYSTEM: {
    12123
    12124             //
    12125             // Use the standard public default protection for these types of devices.
    12126             //
    12127
    12128             RtlCreateSecurityDescriptor(descriptor,
    12129                                         SECURITY_DESCRIPTOR_REVISION );
    12130
    12131             RtlSetDaclSecurityDescriptor(descriptor,
    12132                                          TRUE,
    12133                                          SePublicDefaultUnrestrictedDacl,
    12134                                          FALSE );
    12135
    12136             if(ARGUMENT_PRESENT(SecurityInformation)) {
    12137                 (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
    12138             }
    12139
    12140             break;
    12141         }
    12142
    12143         case FILE_DEVICE_CD_ROM:
    12144         case FILE_DEVICE_MASS_STORAGE:
    12145         case FILE_DEVICE_DISK:
    12146         case FILE_DEVICE_VIRTUAL_DISK:
    12147         case FILE_DEVICE_NETWORK_FILE_SYSTEM:
    12148         case FILE_DEVICE_DFS_FILE_SYSTEM:
    12149         case FILE_DEVICE_NETWORK: {
    12150
    12151             if ((DeviceHasName) &&
    12152                 ((DeviceCharacteristics & FILE_FLOPPY_DISKETTE) != 0)) {
    12153
    12154                 status = RtlCreateSecurityDescriptor(
    12155                             descriptor,
    12156                             SECURITY_DESCRIPTOR_REVISION );
    12157
    12158                 ASSERT( NT_SUCCESS( status ) );
    12159
    12160                 status = RtlSetDaclSecurityDescriptor(
    12161                             descriptor,
    12162                             TRUE,
    12163                             SePublicOpenUnrestrictedDacl,
    12164                             FALSE );
    12165
    12166                 ASSERT( NT_SUCCESS( status ) );
    12167
    12168                 if(ARGUMENT_PRESENT(SecurityInformation)) {
    12169                     (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
    12170                 }
    12171
    12172             } else {
    12173
    12174                 UCHAR i;
    12175                 PACL acl;
    12176                 BOOLEAN aceFound;
    12177                 BOOLEAN aceFoundForCDROM;
    12178                 PACCESS_ALLOWED_ACE ace;
    12179
    12180                 //
    12181                 // Protect the device so that an administrator can run chkdsk
    12182                 // on it. This is done by making a copy of the default public
    12183                 // ACL and changing the accesses granted to the administrators
    12184                 // alias.
    12185                 //
    12186                 // The logic here is:
    12187                 //
    12188                 //      - Copy the public default dacl into another buffer
    12189                 //
    12190                 //      - Find the ACE granting ADMINISTRATORS access
    12191                 //
    12192                 //      - Change the granted access mask of that ACE to give
    12193                 //        administrators write access.
    12194                 //
    12195                 //
    12196
    12197                 acl = ExAllocatePoolWithTag(
    12198                         PagedPool,
    12199                         SePublicDefaultUnrestrictedDacl->AclSize,
    12200                         'eSoI' );
    12201
    12202                 if (!acl) {
    12203                     return NULL;
    12204                 }
    12205
    12206                 RtlCopyMemory( acl,
    12207                                SePublicDefaultUnrestrictedDacl,
    12208                                SePublicDefaultUnrestrictedDacl->AclSize );
    12209
    12210                 //
    12211                 // Find the Administrators ACE
    12212                 //
    12213
    12214                 aceFound = FALSE;
    12215                 aceFoundForCDROM = FALSE;
    12216
    12217                 for ( i = 0, status = RtlGetAce(acl, 0, &ace);
    12218                       NT_SUCCESS(status);
    12219                       i++, status = RtlGetAce(acl, i, &ace)) {
    12220
    12221                     PSID sid;
    12222
    12223                     sid = &(ace->SidStart);
    12224                     if (RtlEqualSid( SeAliasAdminsSid, sid )) {
    12225                         PACCESS_MASK mask;
    12226
    12227                         ace->Mask |= ( GENERIC_READ |
    12228                                        GENERIC_WRITE |
    12229                                        GENERIC_EXECUTE );
    12230
    12231                         aceFound = TRUE;
    12232                     }
    12233
    12234                     if (DeviceType == FILE_DEVICE_CD_ROM) {
    12235
    12236                          if (RtlEqualSid( SeWorldSid, sid )) {
    12237                              ace->Mask |= GENERIC_READ;
    12238                              aceFoundForCDROM = TRUE;
    12239                          }
    12240                      }
    12241                 }
    12242
    12243                 //
    12244                 // If the ACE wasn't found, then the public default ACL has been
    12245                 // changed.  For this case, this code needs to be updated to match
    12246                 // the new public default DACL.
    12247                 //
    12248
    12249                 ASSERT(aceFound == TRUE);
    12250
    12251                 if (DeviceType == FILE_DEVICE_CD_ROM) {
    12252                     ASSERT(aceFoundForCDROM == TRUE);
    12253                 }
    12254
    12255                 //
    12256                 // Finally, build a full security descriptor from the above DACL.
    12257                 //
    12258
    12259                 RtlCreateSecurityDescriptor( descriptor,
    12260                                              SECURITY_DESCRIPTOR_REVISION );
    12261
    12262                 RtlSetDaclSecurityDescriptor( descriptor,
    12263                                               TRUE,
    12264                                               acl,
    12265                                               FALSE );
    12266
    12267                 if(ARGUMENT_PRESENT(SecurityInformation)) {
    12268                     (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
    12269                 }
    12270
    12271                 *AllocatedAcl = acl;
    12272             }
    12273
    12274             break;
    12275         }
    12276
    12277         default: {
    12278
    12279             status = RtlCreateSecurityDescriptor( descriptor,
    12280                                                   SECURITY_DESCRIPTOR_REVISION );
    12281             ASSERT( NT_SUCCESS( status ) );
    12282
    12283             status = RtlSetDaclSecurityDescriptor( descriptor,
    12284                                                    TRUE,
    12285                                                    SePublicOpenUnrestrictedDacl,
    12286                                                    FALSE );
    12287
    12288             if(ARGUMENT_PRESENT(SecurityInformation)) {
    12289                 (*SecurityInformation) |= DACL_SECURITY_INFORMATION;
    12290             }
    12291
    12292             break;
    12293         }
    12294     }
    12295
    12296     return descriptor;
    12297 }

VOID IopCreateVpb | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 4053 of file iosubs.c.

References ExAllocatePoolWithTag, IO_TYPE_VPB, NonPagedPoolMustSucceed, _VPB::RealDevice, _VPB::Size, _VPB::Type, VPB, and _DEVICE_OBJECT::Vpb.

Referenced by IoCreateDevice(), and IoVerifyVolume().

    04056 {
    04057     PVPB Vpb;
    04058
    04059     Vpb = ExAllocatePoolWithTag(
    04060                 NonPagedPoolMustSucceed,
    04061                 sizeof( VPB ),
    04062                 ' bpV'
    04063                 );
    04064
    04065     RtlZeroMemory (Vpb, sizeof(VPB));
    04066     Vpb->Type = IO_TYPE_VPB;
    04067     Vpb->Size = sizeof( VPB );
    04068     Vpb->RealDevice = DeviceObject;
    04069     DeviceObject->Vpb = Vpb;
    04070 }

VOID IopDeallocateApc | ( | IN PKAPC | Apc,
|  | IN PKNORMAL_ROUTINE * | NormalRoutine,
|  | IN PVOID * | NormalContext,
|  | IN PVOID * | SystemArgument1,
|  | IN PVOID * | SystemArgument2
| ) |

Definition at line 1771 of file internal.c.

References ExFreePool(), and PAGED_CODE.

Referenced by IoRaiseHardError(), and IoRaiseInformationalHardError().

    01781                    :
    01782
    01783     This routine is invoked to deallocate an APC that was used to queue a
    01784     request to a target thread.  It simple deallocates the APC.
    01785
    01786 Arguments:
    01787
    01788     Apc - Supplies a pointer to kernel APC structure.
    01789
    01790     NormalRoutine - Supplies a pointer to a pointer to the normal function
    01791         that was specified when the APC was initialied.
    01792
    01793     NormalContext - Supplies a pointer to a pointer to an arbitrary data
    01794         structure that was specified when the APC was initialized.
    01795
    01796     SystemArgument1, SystemArgument2 - Supplies a set of two pointers to
    01797         two arguments that contain untyped data.
    01798
    01799 Return Value:
    01800
    01801     None.
    01802
    01803 --*/
    01804
    01805 {
    01806     UNREFERENCED_PARAMETER( NormalRoutine );
    01807     UNREFERENCED_PARAMETER( NormalContext );
    01808     UNREFERENCED_PARAMETER( SystemArgument1 );
    01809     UNREFERENCED_PARAMETER( SystemArgument2 );
    01810
    01811     PAGED_CODE();
    01812
    01813     //
    01814     // Free the APC.
    01815     //
    01816
    01817     ExFreePool( Apc );
    01818 }

VOID IopDecrementDeviceObjectRef | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN BOOLEAN | AlwaysUnload
| ) |

Definition at line 4022 of file internal.c.

References ASSERT, DOE_DELETE_PENDING, DOE_REMOVE_PENDING, DOE_UNLOAD_PENDING, IopCompleteUnloadOrDelete(), and IopDatabaseLock.

Referenced by IoCreateStreamFileObject(), IoCreateStreamFileObjectLite(), IopCheckVpbMounted(), IopDeleteFile(), IopLoadFileSystemDriver(), and IopParseDevice().

    04029                    :
    04030
    04031     The routine decrements the reference count on a device object.  If the
    04032     reference count goes to zero and the device object is a candidate for deletion
    04033     then IopCompleteUnloadOrDelete is called.  A device object is subject for
    04034     deletion if the AlwaysUnload flag is true, or the device object is pending
    04035     deletion or the driver is pending unload.
    04036
    04037 Arguments:
    04038
    04039     DeviceObject - Supplies the device object whose reference count is to be
    04040                    decremented.
    04041
    04042     AlwaysUnload - Indicates if the driver should be unloaded regardless of the
    04043                    state of the unload flag.
    04044
    04045 Return Value:
    04046
    04047     None.
    04048
    04049 --*/
    04050 {
    04051     KIRQL irql;
    04052
    04053     //
    04054     // Decrement the reference count on the device object.  If this is the last
    04055     // last reason that this mini-file system recognizer needs to stay around,
    04056     // then unload it.
    04057     //
    04058
    04059     ExAcquireSpinLock( &IopDatabaseLock, &irql );
    04060
    04061     ASSERT( DeviceObject->ReferenceCount > 0 );
    04062
    04063     DeviceObject->ReferenceCount--;
    04064
    04065     if (!DeviceObject->ReferenceCount && (AlwaysUnload ||
    04066          DeviceObject->DeviceObjectExtension->ExtensionFlags &
    04067          (DOE_DELETE_PENDING | DOE_UNLOAD_PENDING | DOE_REMOVE_PENDING))) {
    04068
    04069         IopCompleteUnloadOrDelete( DeviceObject, irql );
    04070     } else {
    04071         ExReleaseSpinLock( &IopDatabaseLock, irql );
    04072     }
    04073
    04074 }

VOID IopDeleteDevice | ( | IN PVOID | Object | ) |

Definition at line 769 of file objsup.c.

References ASSERT, ASSERTMSG, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, _DEVICE_OBJECT::DriverObject, ExFreePool(), _VPB::Flags, IopDestroyDeviceNode(), NULL, ObDereferenceObject, PAGED_CODE, _VPB::ReferenceCount, _DEVICE_OBJECT::Vpb, VPB_LOCKED, and VPB_MOUNTED.

Referenced by IopCreateObjectTypes().

    00775                    :
    00776
    00777     This routine is invoked when the reference count for a device object
    00778     becomes zero.  That is, the last reference for the device has gone away.
    00779     This routine ensures that the object is cleaned up and the driver object
    00780     is dereferenced.
    00781
    00782 Arguments:
    00783
    00784     Object - Pointer to the driver object whose reference count has gone
    00785         to zero.
    00786
    00787 Return value:
    00788
    00789     None.
    00790
    00791 --*/
    00792
    00793 {
    00794     PDEVICE_OBJECT deviceObject = (PDEVICE_OBJECT) Object;
    00795     PVPB vpb = NULL;
    00796
    00797     PAGED_CODE();
    00798
    00799     IopDestroyDeviceNode(deviceObject->DeviceObjectExtension->DeviceNode);
    00800
    00801 #if DBG
    00802     IopCheckDeviceNodeTree (deviceObject, NULL);
    00803 #endif
    00804
    00805     //
    00806     // If there's still a VPB attached then free it.
    00807     //
    00808
    00809     vpb = InterlockedExchangePointer(&(deviceObject->Vpb), vpb);
    00810
    00811     if(vpb != NULL) {
    00812
    00813         ASSERTMSG("Unreferenced device object to be deleted is still in use",
    00814                   ((vpb->Flags & (VPB_MOUNTED | VPB_LOCKED)) == 0));
    00815
    00816         ASSERT(vpb->ReferenceCount == 0);
    00817         ExFreePool(vpb);
    00818     }
    00819     if (deviceObject->DriverObject != NULL) {
    00820         ObDereferenceObject( deviceObject->DriverObject );
    00821     }
    00822 }

VOID IopDeleteDriver | ( | IN PVOID | Object | ) |

Definition at line 698 of file objsup.c.

References ASSERT, _DRIVER_EXTENSION::ClientDriverExtension, _DRIVER_OBJECT::DeviceObject, _DRIVER_OBJECT::DriverExtension, _DRIVER_OBJECT::DriverName, _DRIVER_OBJECT::DriverSection, ExFreePool(), extension, MmUnloadSystemImage(), NULL, PAGED_CODE, and _DRIVER_EXTENSION::ServiceKeyName.

Referenced by IopCreateObjectTypes().

    00704                    :
    00705
    00706     This routine is invoked when the reference count for a driver object
    00707     becomes zero.  That is, the last reference for the driver has gone away.
    00708     This routine ensures that the object is cleaned up and the driver
    00709     unloaded.
    00710
    00711 Arguments:
    00712
    00713     Object - Pointer to the driver object whose reference count has gone
    00714         to zero.
    00715
    00716 Return value:
    00717
    00718     None.
    00719
    00720 --*/
    00721
    00722 {
    00723     PDRIVER_OBJECT driverObject = (PDRIVER_OBJECT) Object;
    00724     PIO_CLIENT_EXTENSION extension;
    00725     PIO_CLIENT_EXTENSION nextExtension;
    00726
    00727     PAGED_CODE();
    00728
    00729     ASSERT( !driverObject->DeviceObject );
    00730
    00731     //
    00732     // Free any client driver object extensions.
    00733     //
    00734
    00735     extension = driverObject->DriverExtension->ClientDriverExtension;
    00736     while (extension != NULL) {
    00737
    00738         nextExtension = extension->NextExtension;
    00739         ExFreePool( extension );
    00740         extension = nextExtension;
    00741     }
    00742
    00743     //
    00744     // If there is a driver section then unload the driver.
    00745     //
    00746
    00747     if (driverObject->DriverSection != NULL) {
    00748         MmUnloadSystemImage( driverObject->DriverSection );
    00749     }
    00750
    00751     //
    00752     // Free the pool associated with the name of the driver.
    00753     //
    00754
    00755     if (driverObject->DriverName.Buffer) {
    00756         ExFreePool( driverObject->DriverName.Buffer );
    00757     }
    00758
    00759     //
    00760     // Free the pool associated with the service key name of the driver.
    00761     //
    00762
    00763     if (driverObject->DriverExtension->ServiceKeyName.Buffer) {
    00764         ExFreePool( driverObject->DriverExtension->ServiceKeyName.Buffer );
    00765     }
    00766 }

VOID IopDeleteFile | ( | IN PVOID | Object | ) |

Definition at line 417 of file objsup.c.

References APC_LEVEL, _IRP::AssociatedIrp, _FILE_OBJECT::CompletionContext, _FILE_OBJECT::DeviceObject, DO_NEVER_LAST_DEVICE, _FILE_OBJECT::Event, Executive, ExFreePool(), ExInterlockedAddUlong(), FALSE, _FILE_OBJECT::FileName, _IO_STACK_LOCATION::FileObject, _FILE_OBJECT::Flags, _IRP::Flags, _DEVICE_OBJECT::Flags, FO_DIRECT_DEVICE_OPEN, FO_HANDLE_CREATED, FO_SYNCHRONOUS_IO, IoAllocateIrp(), IoCallDriver, IoFreeIrp(), IoGetAttachedDevice(), IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAcquireFastLock, IopAcquireFileObjectLock(), IopAllocateIrpMustSucceed(), IopCloseFile(), IopDatabaseLock, IopDecrementDeviceObjectRef(), IopDequeueThreadIrp, IopQueueThreadIrp, IopVpbSpinLock, IRP_CLOSE_OPERATION, IRP_MJ_CLOSE, IRP_SYNCHRONOUS_API, KeClearEvent, KeInitializeEvent, KeLowerIrql(), KeRaiseIrql(), KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, NTSTATUS(), NULL, ObDereferenceObject, _IO_COMPLETION_CONTEXT::Port, PsGetCurrentThread, _VPB::ReferenceCount, _DEVICE_OBJECT::ReferenceCount, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserEvent, _IRP::UserIosb, VOID(), and _FILE_OBJECT::Vpb.

Referenced by IopCreateObjectTypes(), and IopParseDevice().

    00423                    :
    00424
    00425     This routine is invoked when the last handle to a specific file handle is
    00426     being closed and the file object is going away.  It is the responsibility
    00427     of this routine to perform the following functions:
    00428
    00429         o  Notify the device driver that the file object is open on that the
    00430            file is being closed.
    00431
    00432         o  Dereference the user's error port for the file object, if there
    00433            is one associated with the file object.
    00434
    00435         o  Decrement the device object reference count.
    00436
    00437 Arguments:
    00438
    00439     Object - Pointer to the file object being deleted.
    00440
    00441 Return Value:
    00442
    00443     None.
    00444
    00445 --*/
    00446
    00447 {
    00448     PIRP irp;
    00449     PIO_STACK_LOCATION irpSp;
    00450     PDEVICE_OBJECT deviceObject;
    00451     IO_STATUS_BLOCK ioStatusBlock;
    00452     KIRQL irql;
    00453     NTSTATUS status;
    00454     PFILE_OBJECT fileObject;
    00455     KEVENT event;
    00456     PVPB vpb;
    00457     BOOLEAN referenceCountDecremented;
    00458
    00459     //
    00460     // Obtain a pointer to the file object.
    00461     //
    00462
    00463     fileObject = (PFILE_OBJECT) Object;
    00464
    00465     //
    00466     // Get a pointer to the first device driver which should be notified that
    00467     // this file is going away.  If the device driver field is NULL, then this
    00468     // file is being shut down due to an error attempting to get it open in the
    00469     // first place, so do not do any further processing.
    00470     //
    00471
    00472     if (fileObject->DeviceObject) {
    00473         if (!(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    00474             deviceObject = IoGetRelatedDeviceObject( fileObject );
    00475         } else {
    00476             deviceObject = IoGetAttachedDevice( fileObject->DeviceObject );
    00477         }
    00478
    00479         //
    00480         // If this file has never had a file handle created for it, and yet
    00481         // it exists, invoke the close file procedure so that the file system
    00482         // gets the cleanup IRP it is expecting before sending the close IRP.
    00483         //
    00484
    00485         if (!(fileObject->Flags & FO_HANDLE_CREATED)) {
    00486             IopCloseFile( (PEPROCESS) NULL,
    00487                           Object,
    00488                           0,
    00489                           1,
    00490                           1 );
    00491         }
    00492
    00493         //
    00494         // If this file is open for synchronous I/O, wait until this thread
    00495         // owns it exclusively since there may still be a thread using it.
    00496         // This occurs when a system service owns the file because it owns
    00497         // the semaphore, but the I/O completion code has already dereferenced
    00498         // the file object itself.  Without waiting here for the same semaphore
    00499         // there would be a race condition in the service who owns it now.  The
    00500         // service needs to be able to access the object w/o it going away after
    00501         // its wait for the file event is satisfied.
    00502         //
    00503
    00504         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    00505
    00506             BOOLEAN interrupted;
    00507
    00508             if (!IopAcquireFastLock( fileObject )) {
    00509                 (VOID) IopAcquireFileObjectLock( fileObject,
    00510                                                  KernelMode,
    00511                                                  FALSE,
    00512                                                  &interrupted );
    00513             }
    00514         }
    00515
    00516         //
    00517         // Reset a local event that can be used to wait for the device driver
    00518         // to close the file.
    00519         //
    00520
    00521         KeInitializeEvent( &event, SynchronizationEvent, FALSE );
    00522
    00523         //
    00524         // Reset the event in the file object.
    00525         //
    00526
    00527         KeClearEvent( &fileObject->Event );
    00528
    00529         //
    00530         // Allocate an I/O Request Packet (IRP) to be used in communicating with
    00531         // the appropriate device driver that the file is being closed.  Notice
    00532         // that the allocation of this packet is done without charging quota so
    00533         // that the operation will not fail.  This is done because there is no
    00534         // way to return an error to the caller at this point.
    00535         //
    00536
    00537         irp = IoAllocateIrp( deviceObject->StackSize, FALSE );
    00538         if (!irp) {
    00539             irp = IopAllocateIrpMustSucceed( deviceObject->StackSize );
    00540         }
    00541
    00542         //
    00543         // Get a pointer to the stack location for the first driver.  This is
    00544         // where the function codes and parameters are placed.
    00545         //
    00546
    00547         irpSp = IoGetNextIrpStackLocation( irp );
    00548
    00549         //
    00550         // Fill in the IRP, indicating that this file object is being deleted.
    00551         //
    00552
    00553         irpSp->MajorFunction = IRP_MJ_CLOSE;
    00554         irpSp->FileObject = fileObject;
    00555         irp->UserIosb = &ioStatusBlock;
    00556         irp->UserEvent = &event;
    00557         irp->Tail.Overlay.OriginalFileObject = fileObject;
    00558         irp->Tail.Overlay.Thread = PsGetCurrentThread();
    00559         irp->AssociatedIrp.SystemBuffer = (PVOID) NULL;
    00560         irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
    00561
    00562         //
    00563         // Place this packet in the thread's I/O pending queue.
    00564         //
    00565
    00566         IopQueueThreadIrp( irp );
    00567
    00568         //
    00569         // Decrement the reference count on the VPB, if necessary.  We
    00570         // have to do this BEFORE handing the Irp to the file system
    00571         // because of a trick the file systems play with close, and
    00572         // believe me, you really don't want to know what it is.
    00573         //
    00574         // Since there is not a error path here (close cannot fail),
    00575         // and the file system is the only ome who can actually synchronize
    00576         // with the actual completion of close processing, the file system
    00577         // is the one responsible for Vpb deletion.
    00578         //
    00579
    00580         vpb = fileObject->Vpb;
    00581
    00582         if (vpb && !(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    00583             ExInterlockedAddUlong( &vpb->ReferenceCount,
    00584                                    0xffffffff,
    00585                                    &IopVpbSpinLock );
    00586         }
    00587
    00588         //
    00589         // If this device object has stated for a fact that it knows it will
    00590         // never have the final non-zero reference count among the other
    00591         // device objects associated with our driver object, then decrement
    00592         // our reference count here BEFORE calling the file system.  This
    00593         // is required because for a special class of device objects, the
    00594         // file system may delete them.
    00595         //
    00596
    00597         if (fileObject->DeviceObject->Flags & DO_NEVER_LAST_DEVICE) {
    00598             ExInterlockedAddUlong( &fileObject->DeviceObject->ReferenceCount,
    00599                                    0xffffffff,
    00600                                    &IopDatabaseLock );
    00601
    00602             referenceCountDecremented = TRUE;
    00603         } else {
    00604             referenceCountDecremented = FALSE;
    00605         }
    00606
    00607         //
    00608         // Give the device driver the packet.  If this request does not work,
    00609         // there is nothing that can be done about it.  This is unfortunate
    00610         // because the driver may have had problems that it was about to
    00611         // report about other operations (e.g., write behind failures, etc.)
    00612         // that it can no longer report.  The reason is that this routine
    00613         // is really initially invoked by NtClose, which has already closed
    00614         // the caller's handle, and that's what the return status from close
    00615         // indicates:  the handle has successfully been closed.
    00616         //
    00617
    00618         status = IoCallDriver( deviceObject, irp );
    00619
    00620         if (status == STATUS_PENDING) {
    00621             (VOID) KeWaitForSingleObject( &event,
    00622                                           Executive,
    00623                                           KernelMode,
    00624                                           FALSE,
    00625                                           (PLARGE_INTEGER) NULL );
    00626         }
    00627
    00628         //
    00629         // Perform any completion operations that need to be performed on
    00630         // the IRP that was used for this request.  This is done here as
    00631         // as opposed to in normal completion code because there is a race
    00632         // condition between when this routine executes if it was invoked
    00633         // from a special kernel APC (e.g., some IRP was just completed and
    00634         // dereferenced this file object for the last time), and when the
    00635         // special kernel APC because of this packet's completion executing.
    00636         //
    00637         // This problem is solved by not having to queue a special kernel
    00638         // APC routine for completion of this packet.  Rather, it is treated
    00639         // much like a synchronous paging I/O operation, except that the
    00640         // packet is not even freed during I/O completion.  This is because
    00641         // the packet is still in this thread's queue, and there is no way
    00642         // to get it out except at APC_LEVEL.  Unfortunately, the part of
    00643         // I/O completion that needs to dequeue the packet is running at
    00644         // DISPATCH_LEVEL.
    00645         //
    00646         // Hence, the packet must be removed from the queue (synchronized,
    00647         // of course), and then it must be freed.
    00648         //
    00649
    00650         KeRaiseIrql( APC_LEVEL, &irql );
    00651         IopDequeueThreadIrp( irp );
    00652         KeLowerIrql( irql );
    00653
    00654         IoFreeIrp( irp );
    00655
    00656         //
    00657         // Free the file name string buffer if there was one.
    00658         //
    00659
    00660         if (fileObject->FileName.Length != 0) {
    00661             ExFreePool( fileObject->FileName.Buffer );
    00662         }
    00663
    00664         //
    00665         // If there was an completion port associated w/this file object, dereference
    00666         // it now, and deallocate the completion context pool.
    00667         //
    00668
    00669         if (fileObject->CompletionContext) {
    00670             ObDereferenceObject( fileObject->CompletionContext->Port );
    00671             ExFreePool( fileObject->CompletionContext );
    00672         }
    00673
    00674         //
    00675         // Get a pointer to the real device object so its reference count
    00676         // can be decremented.
    00677         //
    00678
    00679         deviceObject = fileObject->DeviceObject;
    00680
    00681         //
    00682         // Decrement the reference count on the device object.  Note that
    00683         // if the driver has been marked for an unload operation, and the
    00684         // reference count goes to zero, then the driver may need to be
    00685         // unloaded at this point.
    00686         //
    00687         // Note: only do this if the reference count was not already done
    00688         // above.  The device object may be gone in this case.
    00689         //
    00690
    00691         if (!referenceCountDecremented) {
    00692             IopDecrementDeviceObjectRef( deviceObject, FALSE );
    00693         }
    00694     }
    00695 }

VOID IopDeleteIoCompletion | ( | IN PVOID | Object | ) |

Definition at line 864 of file complete.c.

References IoFreeIrp(), IopCompletionPacketIrp, IopFreeMiniPacket(), Irp, KeRundownQueue(), _IOP_MINI_COMPLETION_PACKET::ListEntry, NULL, and _IOP_MINI_COMPLETION_PACKET::PacketType.

Referenced by IopCreateObjectTypes().

    00870                    :
    00871
    00872     This function is the delete routine for I/O completion objects. Its
    00873     function is to release all the entries in the repsective completion
    00874     queue and to rundown all threads that are current associated.
    00875
    00876 Arguments:
    00877
    00878     Object - Supplies a pointer to an executive I/O completion object.
    00879
    00880 Return Value:
    00881
    00882     None.
    00883
    00884 --*/
    00885
    00886 {
    00887
    00888     PLIST_ENTRY FirstEntry;
    00889     PIRP Irp;
    00890     PLIST_ENTRY NextEntry;
    00891     PIOP_MINI_COMPLETION_PACKET MiniPacket;
    00892
    00893     //
    00894     // Rundown threads associated with the I/O completion object and get
    00895     // the list of unprocessed I/O completion IRPs.
    00896     //
    00897
    00898     FirstEntry = KeRundownQueue((PKQUEUE)Object);
    00899     if (FirstEntry != NULL) {
    00900         NextEntry = FirstEntry;
    00901         do {
    00902             MiniPacket = CONTAINING_RECORD(NextEntry,
    00903                                            IOP_MINI_COMPLETION_PACKET,
    00904                                            ListEntry);
    00905
    00906             NextEntry = NextEntry->Flink;
    00907             if (MiniPacket->PacketType == IopCompletionPacketIrp) {
    00908                 Irp = CONTAINING_RECORD(MiniPacket, IRP, Tail.Overlay.ListEntry);
    00909                 IoFreeIrp(Irp);
    00910
    00911             } else {
    00912                 IopFreeMiniPacket(MiniPacket);
    00913             }
    00914
    00915         } while (FirstEntry != NextEntry);
    00916     }
    00917
    00918     return;
    00919 }
    }

VOID IopDisassociateThreadIrp | ( | VOID |  | ) |

Definition at line 1623 of file internal.c.

References APC_LEVEL, _IRP::CurrentLocation, _IO_STACK_LOCATION::DeviceObject, IoAllocateErrorLogEntry(), IoGetCurrentIrpStackLocation, IopCompletionLock, IopDeadIrp, IoWriteErrorLogEntry(), _ETHREAD::IrpList, KeLowerIrql(), KeRaiseIrql(), NTSTATUS(), NULL, PsGetCurrentThread, _IRP::StackCount, and _IRP::Tail.

Referenced by IoCancelThreadIo().

    01629                    :
    01630
    01631     This routine is invoked when the I/O requests for a thread are being
    01632     cancelled, but there is a packet at the end of the thread's queue that
    01633     has not been completed for such a long period of time that it has timed
    01634     out.  It is this routine's responsibility to try to disassociate that
    01635     IRP with this thread.
    01636
    01637 Arguments:
    01638
    01639     None.
    01640
    01641 Return Value:
    01642
    01643     None.
    01644
    01645 --*/
    01646
    01647 {
    01648     KIRQL irql;
    01649     KIRQL spIrql;
    01650     PIRP irp;
    01651     PETHREAD thread;
    01652     PLIST_ENTRY entry;
    01653     PIO_STACK_LOCATION irpSp;
    01654     PDEVICE_OBJECT deviceObject;
    01655     PDRIVER_OBJECT driverObject;
    01656     WCHAR buffer[512];
    01657     POBJECT_NAME_INFORMATION nameInformation;
    01658     ULONG nameLength;
    01659     NTSTATUS status;
    01660     ULONG response;
    01661     PIO_ERROR_LOG_PACKET errorLogEntry;
    01662
    01663     //
    01664     // Begin by ensuring that the packet has not already been removed from
    01665     // the thread's queue.
    01666     //
    01667
    01668     KeRaiseIrql( APC_LEVEL, &irql );
    01669
    01670     thread = PsGetCurrentThread();
    01671
    01672     //
    01673     // If there are no packets on the IRP list, then simply return now.
    01674     // All of the packets have been fully completed, so the caller will also
    01675     // simply return to its caller.
    01676     //
    01677
    01678     if (IsListEmpty( &thread->IrpList )) {
    01679         KeLowerIrql( irql );
    01680         return;
    01681     }
    01682
    01683     //
    01684     // Get a pointer to the first packet on the queue, and begin examining
    01685     // it.  Note that because the processor is at raised IRQL, and because
    01686     // the packet can only be removed in the context of the currently
    01687     // executing thread, that it is not possible for the packet to be removed
    01688     // from the list.  On the other hand, it IS possible for the packet to
    01689     // be queued to the thread's APC list at this point, and this must be
    01690     // blocked/synchronized in order to examine the request.
    01691     //
    01692     // Begin, therefore, by acquiring the I/O completion spinlock, so that
    01693     // the packet can be safely examined.
    01694     //
    01695
    01696     ExAcquireSpinLock( &IopCompletionLock, &spIrql );
    01697
    01698     //
    01699     // Check to see whether or not the packet has been completed (that is,
    01700     // queued to the current thread).  If not, change threads.
    01701     //
    01702
    01703     entry = thread->IrpList.Flink;
    01704     irp = CONTAINING_RECORD( entry, IRP, ThreadListEntry );
    01705
    01706     if (irp->CurrentLocation == irp->StackCount + 2) {
    01707
    01708         //
    01709         // The request has just gone through enough of completion that
    01710         // queueing it to the thread is inevitable.  Simply release the
    01711         // lock and return.
    01712         //
    01713
    01714         ExReleaseSpinLock( &IopCompletionLock, spIrql );
    01715         KeLowerIrql( irql );
    01716         return;
    01717     }
    01718
    01719     //
    01720     // The packet has been located, and it is not going through completion
    01721     // at this point.  Switch threads, so that it will not complete through
    01722     // this thread, remove the request from this thread's queue, and release
    01723     // the spinlock.  Final processing of the IRP will occur when I/O
    01724     // completion notices that there is no thread associated with the
    01725     // request.  It will essentially drop the I/O on the floor.
    01726     //
    01727     // Also, while the request is still held, attempt to determine on which
    01728     // device object the operation is being performed.
    01729     //
    01730
    01735
    01736     IopDeadIrp = irp;
    01737
    01738     irp->Tail.Overlay.Thread = (PETHREAD) NULL;
    01739     entry = RemoveHeadList( &thread->IrpList );
    01740
    01741     // Initialize the thread entry. Otherwise the assertion in IoFreeIrp
    01742     // called via IopDeadIrp will fail.
    01743     InitializeListHead (&(irp)->ThreadListEntry);
    01744
    01745     irpSp = IoGetCurrentIrpStackLocation( irp );
    01746     if (irp->CurrentLocation <= irp->StackCount) {
    01747         deviceObject = irpSp->DeviceObject;
    01748     } else {
    01749         deviceObject = (PDEVICE_OBJECT) NULL;
    01750     }
    01751     ExReleaseSpinLock( &IopCompletionLock, spIrql );
    01752     KeLowerIrql( irql );
    01753
    01754     //
    01755     // If a device object could be identified then try to write to the event log about this
    01756     // device object.
    01757     //
    01758
    01759     if (deviceObject) {
    01760             errorLogEntry = IoAllocateErrorLogEntry(deviceObject, sizeof(IO_ERROR_LOG_PACKET));
    01761             if (errorLogEntry) {
    01762                 errorLogEntry->ErrorCode = IO_DRIVER_CANCEL_TIMEOUT;
    01763                 IoWriteErrorLogEntry(errorLogEntry);
    01764             }
    01765     }
    01766
    01767     return;
    01768 }

BOOLEAN IopDmaDispatch | ( | IN PKINTERRUPT | Interrupt,
|  | IN PVOID | ServiceContext
| ) |

VOID IopDoNameTransmogrify | ( | IN PIRP | Irp,
|  | IN PFILE_OBJECT | FileObject,
|  | IN PREPARSE_DATA_BUFFER | ReparseBuffer
| ) |

Definition at line 8130 of file iosubs.c.

References ASSERT, ExAllocatePoolWithTag, ExFreePool(), _IRP::IoStatus, Irp, NT_SUCCESS, NULL, PagedPool, _IRP::Tail, and USHORT.

Referenced by IopCompleteRequest(), and IopParseDevice().

    08138                    :
    08139
    08140     This routine is called to do the name grafting needed for junctions.
    08141
    08142 Arguments:
    08143
    08144     Irp - Pointer to the I/O Request Packet (IRP) representing the operation
    08145         to be performed.
    08146
    08147     FileObject - Pointer to the file object whose name is being affected.
    08148
    08149     ReparseBuffer - Pointer to a reparse data buffer that is supposed to contain
    08150         a self-consistent set of names to perform name grafting.
    08151
    08152 Return Value:
    08153
    08154     No explicit return value. The appropriate fields off the IRP are set.
    08155
    08156 Note:
    08157
    08158     This function needs to be kept synchronized with the definition of
    08159     REPARSE_DATA_BUFFER.
    08160
    08161 --*/
    08162
    08163 {
    08164     USHORT pathLength = 0;
    08165     USHORT neededBufferLength = 0;
    08166     PVOID outBuffer = NULL;
    08167     PWSTR pathBuffer = NULL;
    08168
    08169     //
    08170     // We do the appropriate paste of the new name in the FileName buffer
    08171     // and deallocate the buffer that brought the data from the file system.
    08172     //
    08173
    08174     ASSERT( Irp->IoStatus.Status == STATUS_REPARSE );
    08175     ASSERT( Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT );
    08176
    08177     ASSERT( Irp->Tail.Overlay.AuxiliaryBuffer != NULL );
    08178
    08179     ASSERT( ReparseBuffer != NULL );
    08180     ASSERT( ReparseBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT );
    08181     ASSERT( ReparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
    08182     ASSERT( ReparseBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
    08183
    08184 #if DBG
    08185 //    DbgPrint( "iosubs.c DoNameTransmogrify: Tag %x Reserved %x MaximumLength %x FileName %Z\n",
    08186 //              ReparseBuffer->ReparseTag, ReparseBuffer->Reserved, FileObject->FileName.MaximumLength, &(FileObject->FileName) );
    08187 #endif // DBG
    08188
    08189     //
    08190     // Determine whether we have enough data for all the length fields.
    08191     //
    08192     // Determine whether the lengths returned are consistent with the maximum
    08193     // buffer. This is the best self-defense check we can do at this time as
    08194     // the stack pointer is already invalid.
    08195     //
    08196
    08197     if (ReparseBuffer->ReparseDataLength >=
    08198         (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) - REPARSE_DATA_BUFFER_HEADER_SIZE)) {
    08199
    08200         if (MAXIMUM_REPARSE_DATA_BUFFER_SIZE <
    08201             (FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer[0]) +
    08202                 ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength +
    08203                 ReparseBuffer->MountPointReparseBuffer.PrintNameLength)) {
    08204
    08205             Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
    08206         }
    08207     } else {
    08208         Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
    08209     }
    08210
    08211     //
    08212     // The value in  ReparseBuffer->Reserved  is the length of the file
    08213     // name that has still to be parsed.
    08214     //
    08215
    08216     //
    08217     // Copy the buffer when it has the appropriate length, else return a null UNICODE name:
    08218     //   (1) Do defensive sanity checks on the name lengths returned.
    08219     //
    08220     // We only care to do this if we have no error conditions.
    08221     //
    08222
    08223     if (NT_SUCCESS( Irp->IoStatus.Status )) {
    08224
    08225         pathBuffer = (PWSTR)((PCHAR)ReparseBuffer->MountPointReparseBuffer.PathBuffer +
    08226                              ReparseBuffer->MountPointReparseBuffer.SubstituteNameOffset);
    08227         pathLength = ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength;
    08228     }
    08229
    08230     //
    08231     // Notice that if the data returned in AuxiliaryBuffer is not long enough then
    08232     // pathLength has value 0 and pathBuffer has value NULL.
    08233     //
    08234     // The value in  ReparseBuffer->Reserved  is the length of the file name that
    08235     // has still to be parsed.
    08236     //
    08237     // We only care to do this if we have no error conditions.
    08238     //
    08239
    08240     if (ReparseBuffer->Reserved < 0) {
    08241
    08242         //
    08243         // This is an invalid offset.
    08244         //
    08245
    08246         Irp->IoStatus.Status = STATUS_IO_REPARSE_DATA_INVALID;
    08247     }
    08248
    08249     if (NT_SUCCESS( Irp->IoStatus.Status )) {
    08250
    08251         //
    08252         // Check for overflow. (pathLength <= MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
    08253         // so pathLength + sizeof(UNICODE_NULL) cannot overflow.
    08254         //
    08255
    08256         if (((USHORT)MAXUSHORT - ReparseBuffer->Reserved ) > (pathLength +(USHORT)sizeof(UNICODE_NULL))) {
    08257             neededBufferLength = pathLength + ReparseBuffer->Reserved + sizeof( UNICODE_NULL );
    08258             //
    08259             // If the out name buffer isn't large enough, allocate a new one.
    08260             //
    08261
    08262             if (FileObject->FileName.MaximumLength < neededBufferLength) {
    08263                 outBuffer = ExAllocatePoolWithTag( PagedPool,
    08264                                                    neededBufferLength,
    08265                                                    'cFoI' );
    08266                 if (!outBuffer) {
    08267                     Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
    08268                 }
    08269             } else {
    08270                 outBuffer = FileObject->FileName.Buffer;
    08271             }
    08272         } else {
    08273             Irp->IoStatus.Status = STATUS_NAME_TOO_LONG;
    08274         }
    08275     }
    08276
    08277     //
    08278     // Place in the out name buffer the remaining part of the name.
    08279     //
    08280     // We only care to do this if we have no error conditions.
    08281     //
    08282
    08283     if (NT_SUCCESS( Irp->IoStatus.Status )) {
    08284
    08285         if (ReparseBuffer->Reserved) {
    08286
    08287             RtlMoveMemory ( (PCHAR)outBuffer + pathLength,
    08288                             (PCHAR)FileObject->FileName.Buffer +
    08289                                   (FileObject->FileName.Length - ReparseBuffer->Reserved),
    08290                             ReparseBuffer->Reserved );
    08291         }
    08292
    08293         //
    08294         // Copy into the front of the out name buffer the value of the
    08295         // reparse point.
    08296         //
    08297
    08298         if (pathLength) {
    08299
    08300             RtlCopyMemory( (PCHAR)outBuffer,
    08301                            (PCHAR)pathBuffer,
    08302                            pathLength );
    08303         }
    08304
    08305         FileObject->FileName.Length = neededBufferLength - sizeof( UNICODE_NULL );
    08306
    08307         //
    08308         // Free the old name buffer when needed and update the appropriate values.
    08309         //
    08310
    08311         if (outBuffer != FileObject->FileName.Buffer) {
    08312
    08313             if (FileObject->FileName.Buffer != NULL) {
    08314                 ExFreePool( FileObject->FileName.Buffer );
    08315             }
    08316             FileObject->FileName.Buffer = outBuffer;
    08317             FileObject->FileName.MaximumLength = neededBufferLength;
    08318             ((PWSTR)outBuffer)[ (neededBufferLength / sizeof( WCHAR ))-1 ] = UNICODE_NULL;
    08319         }
    08320     }
    08321
    08322     //
    08323     // Free the buffer that came from the file system.
    08324     // NULL the pointer.
    08325     //
    08326
    08327     ExFreePool( ReparseBuffer );
    08328     ReparseBuffer = NULL;
    08329
    08330     //
    08331     // Clear the tag from then Information field.
    08332     //
    08333
    08334     Irp->IoStatus.Information = IO_REPARSE_TAG_RESERVED_ZERO;
    08335 }

VOID IopDropIrp | ( | IN PIRP | Irp,
|  | IN PFILE_OBJECT | FileObject
| ) |

Definition at line 1821 of file internal.c.

References _IRP::AssociatedIrp, ExFreePool(), _IRP::Flags, IoFreeIrp(), IoFreeMdl(), Irp, IRP_CREATE_OPERATION, IRP_DEALLOCATE_BUFFER, IRP_SYNCHRONOUS_API, _IRP::MdlAddress, _MDL::Next, ObDereferenceObject, and _IRP::UserEvent.

    01828                    :
    01829
    01830     This routine attempts to drop everything about the specified IRP on the
    01831     floor.
    01832
    01833 Arguments:
    01834
    01835     Irp - Supplies the I/O Request Packet to be completed to the bit bucket.
    01836
    01837     FileObject - Supplies the file object for which the I/O Request Packet was
    01838         bound.
    01839
    01840 Return Value:
    01841
    01842     None.
    01843
    01844 --*/
    01845
    01846 {
    01847     PMDL mdl;
    01848     PMDL nextMdl;
    01849
    01850     //
    01851     // Free the resources associated with the IRP.
    01852     //
    01853
    01854     if (Irp->Flags & IRP_DEALLOCATE_BUFFER) {
    01855         ExFreePool( Irp->AssociatedIrp.SystemBuffer );
    01856     }
    01857
    01858     if (Irp->MdlAddress) {
    01859         for (mdl = Irp->MdlAddress; mdl; mdl = nextMdl) {
    01860             nextMdl = mdl->Next;
    01861             IoFreeMdl( mdl );
    01862         }
    01863     }
    01864
    01865     if (Irp->UserEvent &&
    01866         FileObject &&
    01867         !(Irp->Flags & IRP_SYNCHRONOUS_API)) {
    01868         ObDereferenceObject( Irp->UserEvent );
    01869     }
    01870
    01871     if (FileObject && !(Irp->Flags & IRP_CREATE_OPERATION)) {
    01872         ObDereferenceObject( FileObject );
    01873     }
    01874
    01875     //
    01876     // Finally, free the IRP itself.
    01877     //
    01878
    01879     IoFreeIrp( Irp );
    01880 }

VOID IopErrorLogThread | ( | IN PVOID | StartContext | ) |

Definition at line 88 of file errorlog.c.

References CHAR, _ERROR_LOG_ENTRY::DeviceObject, _DRIVER_OBJECT::DriverName, _ERROR_LOG_ENTRY::DriverObject, ERROR_LOG_ENTRY, ErrorLogPort, ExAllocatePool, ExFreePool(), ExInterlockedAddUlong(), IO_ERROR_NAME_LENGTH, IO_TYPE_ERROR_MESSAGE, IopErrorLogAllocation, IopErrorLogAllocationLock, IopErrorLogConnectPort(), IopErrorLogGetEntry(), IopErrorLogQueueRequest(), IopErrorLogRequeueEntry(), L, _ERROR_LOG_ENTRY::ListEntry, NT_SUCCESS, NtClose(), NtRequestPort(), NTSTATUS(), NULL, ObDereferenceObject, ObQueryNameString(), PAGED_CODE, PagedPool, PERROR_LOG_ENTRY, _ERROR_LOG_ENTRY::Size, _ERROR_LOG_ENTRY::TimeStamp, and USHORT.

Referenced by IopErrorLogDpc(), and IoWriteErrorLogEntry().

    00094                    :
    00095
    00096     This is the main loop for the I/O error log thread which executes in the
    00097     system process context.  This routine is started when the system is
    00098     initialized.
    00099
    00100 Arguments:
    00101
    00102     StartContext - Startup context; not used.
    00103
    00104 Return Value:
    00105
    00106     None.
    00107
    00108 --*/
    00109
    00110 {
    00111     PERROR_LOG_ENTRY errorLogEntry;
    00112     UNICODE_STRING nameString;
    00113     PLIST_ENTRY listEntry;
    00114     PIO_ERROR_LOG_MESSAGE errorMessage;
    00115     NTSTATUS status;
    00116     PELF_PORT_MSG portMessage;
    00117     PCHAR objectName;
    00118     ULONG messageLength;
    00119     ULONG driverNameLength;
    00120     ULONG deviceNameLength;
    00121     ULONG objectNameLength;
    00122     ULONG remainingLength;
    00123     ULONG stringLength;
    00124     CHAR nameBuffer[IO_ERROR_NAME_LENGTH+sizeof( OBJECT_NAME_INFORMATION )];
    00125     PDRIVER_OBJECT driverObject;
    00126     POBJECT_NAME_INFORMATION nameInformation;
    00127     PIO_ERROR_LOG_PACKET errorData;
    00128     PWSTR string;
    00129
    00130     PAGED_CODE();
    00131
    00132     UNREFERENCED_PARAMETER( StartContext );
    00133
    00134     //
    00135     // Check to see whether a connection has been made to the error log
    00136     // port.  If the port is not connected return.
    00137     //
    00138
    00139     if (!IopErrorLogConnectPort()) {
    00140
    00141         //
    00142         // The port could not be connected.  A timer was started that will
    00143         // try again later.
    00144         //
    00145
    00146         return;
    00147     }
    00148
    00149     //
    00150     // Allocate and zero the port message structure, include space for the
    00151     // name of the device and driver.
    00152     //
    00153
    00154     messageLength = IO_ERROR_LOG_MESSAGE_LENGTH;
    00155     portMessage = ExAllocatePool(PagedPool, messageLength);
    00156
    00157     if (portMessage == NULL) {
    00158
    00159         //
    00160         // The message buffer could not be allocated. Request that
    00161         // the error log thread routine be called again later.
    00162         //
    00163
    00164         IopErrorLogQueueRequest();
    00165         return;
    00166     }
    00167
    00168     RtlZeroMemory( portMessage, sizeof( *portMessage ) );
    00169     portMessage->MessageType = IO_ERROR_LOG;
    00170     errorMessage = &portMessage->u.IoErrorLogMessage;
    00171
    00172     nameInformation = (PVOID) &nameBuffer;
    00173
    00174     //
    00175     // Now enter the main loop for this thread.  This thread performs the
    00176     // following operations:
    00177     //
    00178     //   1)  If a connection has been made to the error log port, dequeue a
    00179     //       packet from the queue head and attempt to send it to the port.
    00180     //
    00181     //   2)  If the send works, loop sending packets until there are no more
    00182     //       packets;  otherwise, indicate that the connection has been broken,
    00183     //       cleanup, place the packet back onto the head of the queue and
    00184     //       return.
    00185     //
    00186     //   3)  After all the packets are sent clear the pending variable and
    00187     //       return.
    00188     //
    00189
    00190     for (;;) {
    00191
    00192         //
    00193         // Loop dequeueing  packets from the queue head and attempt to send
    00194         // each to the port.
    00195         //
    00196         // If the send works, continue looping until there are no more packets.
    00197         // Otherwise, indicate that the connection has been broken, cleanup,
    00198         // place the packet back onto the head of the queue, and start from the
    00199         // top of the loop again.
    00200         //
    00201
    00202         if (!(listEntry = IopErrorLogGetEntry())) {
    00203             break;
    00204         }
    00205
    00206         errorLogEntry = CONTAINING_RECORD( listEntry,
    00207                                            ERROR_LOG_ENTRY,
    00208                                            ListEntry );
    00209
    00210         //
    00211         // The size of errorLogEntry is ERROR_LOG_ENTRY +
    00212         // IO_ERROR_LOG_PACKET + (Extra Dump data).  The size of the
    00213         // initial message length should be IO_ERROR_LOG_MESSAGE +
    00214         // (Extra Dump data), since IO_ERROR_LOG_MESSAGE contains an
    00215         // IO_ERROR_LOG_PACKET. Using the above calculations set the
    00216         // message length.
    00217         //
    00218
    00219         messageLength = sizeof( IO_ERROR_LOG_MESSAGE ) -
    00220             sizeof( ERROR_LOG_ENTRY ) - sizeof( IO_ERROR_LOG_PACKET ) +
    00221             errorLogEntry->Size;
    00222
    00223         errorData = (PIO_ERROR_LOG_PACKET) (errorLogEntry + 1);
    00224
    00225         //
    00226         // Copy the error log packet and the extra data to the message.
    00227         //
    00228
    00229         RtlMoveMemory( &errorMessage->EntryData,
    00230                        errorData,
    00231                        errorLogEntry->Size - sizeof( ERROR_LOG_ENTRY ) );
    00232
    00233         errorMessage->TimeStamp = errorLogEntry->TimeStamp;
    00234         errorMessage->Type = IO_TYPE_ERROR_MESSAGE;
    00235
    00236         //
    00237         // Add the driver and device name string.  These strings go
    00238         // before the error log strings.  Just write over the current
    00239         // strings and they will be recopied later.
    00240         //
    00241
    00242         if (errorData->NumberOfStrings != 0) {
    00243
    00244             //
    00245             // Start the driver and device strings where the current
    00246             // strings start.
    00247             //
    00248
    00249             objectName = (PCHAR) (&errorMessage->EntryData) +
    00250                                  errorData->StringOffset;
    00251
    00252         } else {
    00253
    00254             //
    00255             // Put the driver and device strings at the end of the
    00256             // data.
    00257             //
    00258
    00259             objectName = (PCHAR) errorMessage + messageLength;
    00260
    00261         }
    00262
    00263         //
    00264         // Make sure the driver offset starts on an even bountry.
    00265         //
    00266
    00267         objectName = (PCHAR) ((ULONG_PTR) (objectName + sizeof(WCHAR) - 1) &
    00268             ~(ULONG_PTR)(sizeof(WCHAR) - 1));
    00269
    00270         errorMessage->DriverNameOffset = (ULONG)(objectName - (PCHAR) errorMessage);
    00271
    00272         remainingLength = (ULONG)((PCHAR) portMessage + IO_ERROR_LOG_MESSAGE_LENGTH
    00273                             - objectName);
    00274
    00275         //
    00276         // Calculate the length of the driver name and
    00277         // the device name. If the driver object has a name then get
    00278         // it from there; otherwise try to query the device object.
    00279         //
    00280
    00281         driverObject = errorLogEntry->DriverObject;
    00282         driverNameLength = 0;
    00283
    00284         if (driverObject != NULL) {
    00285             if (driverObject->DriverName.Buffer != NULL) {
    00286
    00287                 nameString.Buffer = driverObject->DriverName.Buffer;
    00288                 driverNameLength = driverObject->DriverName.Length;
    00289             }
    00290
    00291             if (driverNameLength == 0) {
    00292
    00293                 //
    00294                 // Try to query the driver object for a name.
    00295                 //
    00296
    00297                 status = ObQueryNameString( driverObject,
    00298                                             nameInformation,
    00299                                             IO_ERROR_NAME_LENGTH + sizeof( OBJECT_NAME_INFORMATION ),
    00300                                             &objectNameLength );
    00301
    00302                 if (!NT_SUCCESS( status ) || !nameInformation->Name.Length) {
    00303
    00304                     //
    00305                     // No driver name was available.
    00306                     //
    00307
    00308                     driverNameLength = 0;
    00309
    00310                 } else {
    00311                     nameString = nameInformation->Name;
    00312                 }
    00313
    00314             }
    00315
    00316         } else {
    00317
    00318             //
    00319             // If no driver object, this message must be from the
    00320             // kernel.   We need to point the eventlog service to
    00321             // an event message file containing ntstatus messages,
    00322             // ie, ntdll, we do this by claiming this event is an
    00323             // application popup.
    00324             //
    00325
    00326             nameString.Buffer = L"Application Popup";
    00327             driverNameLength = wcslen(nameString.Buffer) * sizeof(WCHAR);
    00328         }
    00329
    00330         if (driverNameLength != 0 ) {
    00331
    00332             //
    00333             // Pick out the module name.
    00334             //
    00335
    00336             string = nameString.Buffer +
    00337                 (driverNameLength / sizeof(WCHAR));
    00338
    00339             driverNameLength = sizeof(WCHAR);
    00340             string--;
    00341             while (*string != L'\\' && string != nameString.Buffer) {
    00342                 string--;
    00343                 driverNameLength += sizeof(WCHAR);
    00344             }
    00345
    00346             if (*string == L'\\') {
    00347                 string++;
    00348                 driverNameLength -= sizeof(WCHAR);
    00349             }
    00350
    00351             //
    00352             // Ensure there is enough room for the driver name.
    00353             // Save space for 3 NULLs one for the driver name,
    00354             // one for the device name and one for strings.
    00355             //
    00356
    00357             if (driverNameLength > remainingLength - (3 * sizeof(WCHAR))) {
    00358                 driverNameLength = remainingLength - (3 * sizeof(WCHAR));
    00359             }
    00360
    00361             RtlMoveMemory(
    00362                 objectName,
    00363                 string,
    00364                 driverNameLength
    00365                 );
    00366
    00367         }
    00368
    00369         //
    00370         // Add a null after the driver name even if there is no
    00371         // driver name.
    00372         //
    00373
    00374        *((PWSTR) (objectName + driverNameLength)) = L'\0';
    00375        driverNameLength += sizeof(WCHAR);
    00376
    00377         //
    00378         // Determine where the next string goes.
    00379         //
    00380
    00381         objectName += driverNameLength;
    00382         remainingLength -= driverNameLength;
    00383
    00384         errorMessage->EntryData.StringOffset = (USHORT)(objectName - (PCHAR) errorMessage);
    00385
    00386         if (errorLogEntry->DeviceObject != NULL) {
    00387
    00388             status = ObQueryNameString( errorLogEntry->DeviceObject,
    00389                                         nameInformation,
    00390                                         IO_ERROR_NAME_LENGTH + sizeof( OBJECT_NAME_INFORMATION ) - driverNameLength,
    00391                                         &objectNameLength );
    00392
    00393             if (!NT_SUCCESS( status ) || !nameInformation->Name.Length) {
    00394
    00395                 //
    00396                 // No device name was available. Add a Null string.
    00397                 //
    00398
    00399                 nameInformation->Name.Length = 0;
    00400                 nameInformation->Name.Buffer = L"\0";
    00401
    00402             }
    00403
    00404             //
    00405             // No device name was available. Add a Null string.
    00406             // Always add a device name string so that the
    00407             // insertion string counts are correct.
    00408             //
    00409
    00410         } else {
    00411
    00412                 //
    00413                 // No device name was available. Add a Null string.
    00414                 // Always add a device name string so that the
    00415                 // insertion string counts are correct.
    00416                 //
    00417
    00418                 nameInformation->Name.Length = 0;
    00419                 nameInformation->Name.Buffer = L"\0";
    00420
    00421         }
    00422
    00423         deviceNameLength = nameInformation->Name.Length;
    00424
    00425         //
    00426         // Ensure there is enough room for the device name.
    00427         // Save space for a NULL.
    00428         //
    00429
    00430         if (deviceNameLength > remainingLength - (2 * sizeof(WCHAR))) {
    00431
    00432             deviceNameLength = remainingLength - (2 * sizeof(WCHAR));
    00433
    00434         }
    00435
    00436         RtlMoveMemory( objectName,
    00437                        nameInformation->Name.Buffer,
    00438                        deviceNameLength );
    00439
    00440         //
    00441         // Add a null after the device name even if there is no
    00442         // device name.
    00443         //
    00444
    00445         *((PWSTR) (objectName + deviceNameLength)) = L'\0';
    00446         deviceNameLength += sizeof(WCHAR);
    00447
    00448         //
    00449         // Update the string count for the device object.
    00450         //
    00451
    00452         errorMessage->EntryData.NumberOfStrings++;
    00453         objectName += deviceNameLength;
    00454         remainingLength -= deviceNameLength;
    00455
    00456         if (errorData->NumberOfStrings) {
    00457
    00458             stringLength = errorLogEntry->Size - sizeof( ERROR_LOG_ENTRY ) -
    00459                             errorData->StringOffset;
    00460
    00461             //
    00462             // Ensure there is enough room for the strings.
    00463             // Save space for a NULL.
    00464             //
    00465
    00466             if (stringLength > remainingLength - sizeof(WCHAR)) {
    00467
    00468
    00469                 messageLength -= stringLength - remainingLength;
    00470                 stringLength = remainingLength - sizeof(WCHAR);
    00471
    00472             }
    00473
    00474             //
    00475             // Copy the strings to the end of the message.
    00476             //
    00477
    00478             RtlMoveMemory( objectName,
    00479                            (PCHAR) errorData + errorData->StringOffset,
    00480                            stringLength );
    00481
    00482             //
    00483             // Add a null after the strings
    00484             //
    00485             //
    00486
    00487            *((PWSTR) (objectName + stringLength)) = L'\0';
    00488
    00489         }
    00490
    00491         //
    00492         // Update the message length.
    00493         //
    00494
    00495         errorMessage->DriverNameLength = (USHORT) driverNameLength;
    00496         messageLength += deviceNameLength + driverNameLength;
    00497         errorMessage->Size = (USHORT) messageLength;
    00498
    00499         messageLength += FIELD_OFFSET ( ELF_PORT_MSG, u ) -
    00500             FIELD_OFFSET (ELF_PORT_MSG, MessageType);
    00501
    00502         portMessage->PortMessage.u1.s1.TotalLength = (USHORT)
    00503             (sizeof( PORT_MESSAGE ) + messageLength);
    00504         portMessage->PortMessage.u1.s1.DataLength = (USHORT) (messageLength);
    00505         status = NtRequestPort( ErrorLogPort, (PPORT_MESSAGE) portMessage );
    00506
    00507         if (!NT_SUCCESS( status )) {
    00508
    00509             //
    00510             // The send failed.  Place the packet back onto the head of
    00511             // the error log queue, forget the current connection since
    00512             // it no longer works, and close the handle to the port.
    00513             // Set a timer up for another attempt later.
    00514             // Finally, exit the loop since there is no connection
    00515             // to do any work on.
    00516             //
    00517
    00518             NtClose( ErrorLogPort );
    00519
    00520             IopErrorLogRequeueEntry( &errorLogEntry->ListEntry );
    00521
    00522             IopErrorLogQueueRequest();
    00523
    00524             break;
    00525
    00526         } else {
    00527
    00528             //
    00529             // The send worked fine.  Free the packet and the update
    00530             // the allocation count.
    00531             //
    00532
    00533             ExInterlockedAddUlong( &IopErrorLogAllocation,
    00534                                    (ULONG) ( -errorLogEntry->Size ),
    00535                                    &IopErrorLogAllocationLock );
    00536
    00537             //
    00538             // Dereference the object pointers now that the name has been
    00539             // captured.
    00540             //
    00541
    00542
    00543             if (errorLogEntry->DeviceObject != NULL) {
    00544                 ObDereferenceObject( errorLogEntry->DeviceObject );
    00545             }
    00546
    00547             if (driverObject != NULL) {
    00548                 ObDereferenceObject( errorLogEntry->DriverObject );
    00549             }
    00550
    00551             ExFreePool( errorLogEntry );
    00552
    00553         } // if
    00554
    00555     } // for
    00556
    00557     //
    00558     // Finally, free the message buffer and return.
    00559     //
    00560
    00561     ExFreePool(portMessage);
    00562
    00563 }

VOID IopExceptionCleanup | ( | IN PFILE_OBJECT | FileObject,
|  | IN PIRP | Irp,
|  | IN PKEVENT EventObject | OPTIONAL,
|  | IN PKEVENT KernelEvent | OPTIONAL
| ) |

Definition at line 1934 of file internal.c.

References _IRP::AssociatedIrp, ExFreePool(), FO_SYNCHRONOUS_IO, IoFreeIrp(), IoFreeMdl(), IopReleaseFileObjectLock, Irp, _IRP::MdlAddress, NULL, ObDereferenceObject, and PAGED_CODE.

Referenced by BuildQueryDirectoryIrp(), IopSetEaOrQuotaInformationFile(), IopXxxControlFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtQueryEaFile(), NtQueryInformationFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetEaFile(), NtSetInformationFile(), NtSetVolumeInformationFile(), NtUnlockFile(), NtWriteFile(), and NtWriteFileGather().

    01943                    :
    01944
    01945     This routine performs generalized cleanup for the I/O system services when
    01946     an exception occurs during caller parameter processing.  This routine
    01947     performs the following steps:
    01948
    01949         o   If a system buffer was allocated it is freed.
    01950
    01951         o   If an MDL was allocated it is freed.
    01952
    01953         o   The IRP is freed.
    01954
    01955         o   If the file object is opened for synchronous I/O, the semaphore
    01956             is released.
    01957
    01958         o   If an event object was referenced it is dereferenced.
    01959
    01960         o   If a kernel event was allocated, free it.
    01961
    01962         o   The file object is dereferenced.
    01963
    01964 Arguments:
    01965
    01966     FileObject - Pointer to the file object currently being worked on.
    01967
    01968     Irp - Pointer to the IRP allocated to handle the I/O request.
    01969
    01970     EventObject - Optional pointer to a referenced event object.
    01971
    01972     KernelEvent - Optional pointer to an allocated kernel event.
    01973
    01974 Return Value:
    01975
    01976     None.
    01977
    01978 --*/
    01979
    01980 {
    01981     PAGED_CODE();
    01982
    01983     //
    01984     // If a system buffer was allocated from nonpaged pool, free it.
    01985     //
    01986
    01987     if (Irp->AssociatedIrp.SystemBuffer != NULL) {
    01988         ExFreePool( Irp->AssociatedIrp.SystemBuffer );
    01989     }
    01990
    01991     //
    01992     // If an MDL was allocated, free it.
    01993     //
    01994
    01995     if (Irp->MdlAddress != NULL) {
    01996         IoFreeMdl( Irp->MdlAddress );
    01997     }
    01998
    01999     //
    02000     // Free the I/O Request Packet.
    02001     //
    02002
    02003     IoFreeIrp( Irp );
    02004
    02005     //
    02006     // Finally, release the synchronization semaphore if it is currently
    02007     // held, dereference the event if one was specified, free the kernel
    02008     // event if one was allocated, and dereference the file object.
    02009     //
    02010
    02011     if (FileObject->Flags & FO_SYNCHRONOUS_IO) {
    02012         IopReleaseFileObjectLock( FileObject );
    02013     }
    02014
    02015     if (ARGUMENT_PRESENT( EventObject )) {
    02016         ObDereferenceObject( EventObject );
    02017     }
    02018
    02019     if (ARGUMENT_PRESENT( KernelEvent )) {
    02020         ExFreePool( KernelEvent );
    02021     }
    02022
    02023     ObDereferenceObject( FileObject );
    02024
    02025     return;
    02026 }

LONG IopExceptionFilter | ( | IN PEXCEPTION_POINTERS | ExceptionPointers,
|  | OUT PNTSTATUS | ExceptionCode
| ) |

Definition at line 1883 of file internal.c.

References EXCEPTION_EXECUTE_HANDLER.

Referenced by IopCompleteRequest(), NtReadFile(), NtReadFileScatter(), NtWriteFile(), and NtWriteFileGather().

    01890                    :
    01891
    01892     This routine is invoked when an exception occurs to determine whether or
    01893     not the exception was due to an error that caused an in-page error status
    01894     code exception to be raised.  If so, then this routine changes the code
    01895     in the exception record to the actual error code that was originally
    01896     raised.
    01897
    01898 Arguments:
    01899
    01900     ExceptionPointer - Pointer to the exception record.
    01901
    01902     ExceptionCode - Variable to receive actual exception code.
    01903
    01904 Return Value:
    01905
    01906     The function value indicates that the exception handler is to be executed.
    01907
    01908 --*/
    01909
    01910 {
    01911     //
    01912     // Simply check for an in-page error status code and, if the conditions
    01913     // are right, replace it with the actual status code.
    01914     //
    01915
    01916     *ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode;
    01917     if (*ExceptionCode == STATUS_IN_PAGE_ERROR &&
    01918         ExceptionPointer->ExceptionRecord->NumberParameters >= 3) {
    01919         *ExceptionCode = (LONG) ExceptionPointer->ExceptionRecord->ExceptionInformation[2];
    01920     }
    01921
    01922     //
    01923     // Translate alignment warnings into alignment errors.
    01924     //
    01925
    01926     if (*ExceptionCode == STATUS_DATATYPE_MISALIGNMENT) {
    01927         *ExceptionCode = STATUS_DATATYPE_MISALIGNMENT_ERROR;
    01928     }
    01929
    01930     return EXCEPTION_EXECUTE_HANDLER;
    01931 }

NTSTATUS FASTCALL IopfCallDriver | ( | PDEVICE_OBJECT | DeviceObject,
|  | PIRP | Irp
| ) |

| Referenced by IopSetIoRoutines().

VOID FASTCALL IopfCompleteRequest | ( | IN PIRP | Irp,
|  | IN CCHAR | PriorityBost
| ) |

Definition at line 3180 of file iosubs.c.

References NULL, and ZeroIrpStackLocation.

Referenced by IopSetIoRoutines(), and IovCompleteRequest().

    03187                    :
    03188
    03189     This routine is invoked to complete an I/O request.  It is invoked by the
    03190     driver in its DPC routine to perform the final completion of the IRP.  The
    03191     functions performed by this routine are as follows.
    03192
    03193         1.  A check is made to determine whether the packet's stack locations
    03194             have been exhausted.  If not, then the stack location pointer is set
    03195             to the next location and if there is a routine to be invoked, then
    03196             it will be invoked.  This continues until there are either no more
    03197             routines which are interested or the packet runs out of stack.
    03198
    03199             If a routine is invoked to complete the packet for a specific driver
    03200             which needs to perform work a lot of work or the work needs to be
    03201             performed in the context of another process, then the routine will
    03202             return an alternate success code of STATUS_MORE_PROCESSING_REQUIRED.
    03203             This indicates that this completion routine should simply return to
    03204             its caller because the operation will be "completed" by this routine
    03205             again sometime in the future.
    03206
    03207         2.  A check is made to determine whether this IRP is an associated IRP.
    03208             If it is, then the count on the master IRP is decremented.  If the
    03209             count for the master becomes zero, then the master IRP will be
    03210             completed according to the steps below taken for a normal IRP being
    03211             completed.  If the count is still non-zero, then this IRP (the one
    03212             being completed) will simply be deallocated.
    03213
    03214         3.  If this is paging I/O or a close operation, then simply write the
    03215             I/O status block and set the event to the signaled state, and
    03216             dereference the event.  If this is paging I/O, deallocate the IRP
    03217             as well.
    03218
    03219         4.  Unlock the pages, if any, specified by the MDL by calling
    03220             MmUnlockPages.
    03221
    03222         5.  A check is made to determine whether or not completion of the
    03223             request can be deferred until later.  If it can be, then this
    03224             routine simply exits and leaves it up to the originator of the
    03225             request to fully complete the IRP.  By not initializing and queueing
    03226             the special kernel APC to the calling thread (which is the current
    03227             thread by definition), a lot of interrupt and queueing processing
    03228             can be avoided.
    03229
    03230
    03231         6.  The final rundown routine is invoked to queue the request packet to
    03232             the target (requesting) thread as a special kernel mode APC.
    03233
    03234 Arguments:
    03235
    03236     Irp - Pointer to the I/O Request Packet to complete.
    03237
    03238     PriorityBoost - Supplies the amount of priority boost that is to be given
    03239         to the target thread when the special kernel APC is queued.
    03240
    03241 Return Value:
    03242
    03243     None.
    03244
    03245 --*/
    03246
    03247 #define ZeroIrpStackLocation( IrpSp ) {         \
    03248     (IrpSp)->MinorFunction = 0;                 \
    03249     (IrpSp)->Flags = 0;                         \
    03250     (IrpSp)->Control = 0 ;                      \
    03251     (IrpSp)->Parameters.Others.Argument1 = 0;   \
    03252     (IrpSp)->Parameters.Others.Argument2 = 0;   \
    03253     (IrpSp)->Parameters.Others.Argument3 = 0;   \
    03254     (IrpSp)->Parameters.Others.Argument4 = 0;   \
    03255     (IrpSp)->FileObject = (PFILE_OBJECT) NULL; }
    03256
    03257 {
    03258     PIRP masterIrp;
    03259     NTSTATUS status;
    03260     PIO_STACK_LOCATION stackPointer;
    03261     PMDL mdl;
    03262     PETHREAD thread;
    03263     PFILE_OBJECT fileObject;
    03264     KIRQL irql;
    03265     PVOID saveAuxiliaryPointer = NULL;
    03266
    03267     //
    03268     // Begin by ensuring that this packet has not already been completed
    03269     // by someone.
    03270     //
    03271
    03272     if (Irp->CurrentLocation > (CCHAR) (Irp->StackCount + 1) ||
    03273         Irp->Type != IO_TYPE_IRP) {
    03274         KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR) Irp, __LINE__, 0, 0 );
    03275     }
    03276
    03277     //
    03278     // Ensure that the packet being completed really is still an IRP.
    03279     //
    03280
    03281     ASSERT( Irp->Type == IO_TYPE_IRP );
    03282
    03283     //
    03284     // Ensure that no one believes that this request is still in a cancelable
    03285     // state.
    03286     //
    03287
    03288     ASSERT( !Irp->CancelRoutine );
    03289
    03290     //
    03291     // Ensure that the packet is not being completed with a thoroughly
    03292     // confusing status code.  Actually completing a packet with a pending
    03293     // status probably means that someone forgot to set the real status in
    03294     // the packet.
    03295     //
    03296
    03297     ASSERT( Irp->IoStatus.Status != STATUS_PENDING );
    03298
    03299     //
    03300     // Ensure that the packet is not being completed with a minus one.  This
    03301     // is apparently a common problem in some drivers, and has no meaning
    03302     // as a status code.
    03303     //
    03304
    03305     ASSERT( Irp->IoStatus.Status != 0xffffffff );
    03306
    03307     //
    03308     // Ensure that if this is a paging I/O operation, and it failed, that the
    03309     // reason for the failure isn't because quota was exceeded.
    03310     //
    03311
    03312     ASSERT( !(Irp->Flags & IRP_PAGING_IO && Irp->IoStatus.Status == STATUS_QUOTA_EXCEEDED ) );
    03313
    03314     //
    03315     // Now check to see whether this is the last driver that needs to be
    03316     // invoked for this packet.  If not, then bump the stack and check to
    03317     // see whether the driver wishes to see the completion.  As each stack
    03318     // location is examined, invoke any routine which needs to be invoked.
    03319     // If the routine returns STATUS_MORE_PROCESSING_REQUIRED, then stop the
    03320     // processing of this packet.
    03321     //
    03322
    03323     for (stackPointer = IoGetCurrentIrpStackLocation( Irp ),
    03324          Irp->CurrentLocation++,
    03325          Irp->Tail.Overlay.CurrentStackLocation++;
    03326          Irp->CurrentLocation <= (CCHAR) (Irp->StackCount + 1);
    03327          stackPointer++,
    03328          Irp->CurrentLocation++,
    03329          Irp->Tail.Overlay.CurrentStackLocation++) {
    03330
    03331         //
    03332         // A stack location was located.  Check to see whether or not it
    03333         // has a completion routine and if so, whether or not it should be
    03334         // invoked.
    03335         //
    03336         // Begin by saving the pending returned flag in the current stack
    03337         // location in the fixed part of the IRP.
    03338         //
    03339
    03340         Irp->PendingReturned = stackPointer->Control & SL_PENDING_RETURNED;
    03341
    03342         if ( (NT_SUCCESS( Irp->IoStatus.Status ) &&
    03343              stackPointer->Control & SL_INVOKE_ON_SUCCESS) ||
    03344              (!NT_SUCCESS( Irp->IoStatus.Status ) &&
    03345              stackPointer->Control & SL_INVOKE_ON_ERROR) ||
    03346              (Irp->Cancel &&
    03347              stackPointer->Control & SL_INVOKE_ON_CANCEL)
    03348            ) {
    03349
    03350             //
    03351             // This driver has specified a completion routine.  Invoke the
    03352             // routine passing it a pointer to its device object and the
    03353             // IRP that is being completed.
    03354             //
    03355
    03356             ZeroIrpStackLocation( stackPointer );
    03357
    03358             PERFINFO_DRIVER_COMPLETIONROUTINE_CALL(Irp, stackPointer);
    03359
    03360             status = stackPointer->CompletionRoutine( (PDEVICE_OBJECT) (Irp->CurrentLocation == (CCHAR) (Irp->StackCount + 1) ?
    03361                                                       (PDEVICE_OBJECT) NULL :
    03362                                                       IoGetCurrentIrpStackLocation( Irp )->DeviceObject),
    03363                                                       Irp,
    03364                                                       stackPointer->Context );
    03365
    03366             PERFINFO_DRIVER_COMPLETIONROUTINE_RETURN(Irp, stackPointer);
    03367
    03368             if (status == STATUS_MORE_PROCESSING_REQUIRED) {
    03369
    03370                 //
    03371                 // Note:  Notice that if the driver has returned the above
    03372                 //        status value, it may have already DEALLOCATED the
    03373                 //        packet!  Therefore, do NOT touch any part of the
    03374                 //        IRP in the following code.
    03375                 //
    03376
    03377                 return;
    03378             }
    03379
    03380         } else {
    03381             if (Irp->PendingReturned && Irp->CurrentLocation <= Irp->StackCount) {
    03382                 IoMarkIrpPending( Irp );
    03383             }
    03384             ZeroIrpStackLocation( stackPointer );
    03385         }
    03386     }
    03387
    03388     //
    03389     // Check to see whether this is an associated IRP.  If so, then decrement
    03390     // the count in the master IRP.  If the count is decremented to zero,
    03391     // then complete the master packet as well.
    03392     //
    03393
    03394     if (Irp->Flags & IRP_ASSOCIATED_IRP) {
    03395         ULONG count;
    03396         masterIrp = Irp->AssociatedIrp.MasterIrp;
    03397         count = ExInterlockedAddUlong( (PULONG) &masterIrp->AssociatedIrp.IrpCount,
    03398                                        0xffffffff,
    03399                                        &IopDatabaseLock );
    03400
    03401         //
    03402         // Deallocate this packet and any MDLs that are associated with it
    03403         // by either doing direct deallocations if they were allocated from
    03404         // a zone or by queueing the packet to a thread to perform the
    03405         // deallocation.
    03406         //
    03407         // Also, check the count of the master IRP to determine whether or not
    03408         // the count has gone to zero.  If not, then simply get out of here.
    03409         // Otherwise, complete the master packet.
    03410         //
    03411
    03412         Irp->Tail.Overlay.Thread = masterIrp->Tail.Overlay.Thread;
    03413         IopFreeIrpAndMdls( Irp );
    03414         if (count == 1) {
    03415             IoCompleteRequest( masterIrp, PriorityBoost );
    03416         }
    03417         return;
    03418     }
    03419
    03420     //
    03421     // Check to see if we have a name junction. If so set the stage to
    03422     // transmogrify the reparse point data in IopCompleteRequest.
    03423     //
    03424
    03425     if ((Irp->IoStatus.Status == STATUS_REPARSE )  &&
    03426         (Irp->IoStatus.Information > IO_REPARSE_TAG_RESERVED_RANGE)) {
    03427
    03428         if (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) {
    03429
    03430             //
    03431             // For name junctions, we save the pointer to the auxiliary
    03432             // buffer and use it below.
    03433             //
    03434
    03435             ASSERT( Irp->Tail.Overlay.AuxiliaryBuffer != NULL );
    03436
    03437             saveAuxiliaryPointer = (PVOID) Irp->Tail.Overlay.AuxiliaryBuffer;
    03438
    03439             //
    03440             // We NULL the entry to avoid its de-allocation at this time.
    03441             // This buffer get deallocated in IopDoNameTransmogrify
    03442             //
    03443
    03444             Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
    03445         } else {
    03446
    03447             //
    03448             // Fail the request. A driver needed to act on this IRP prior
    03449             // to getting to this point.
    03450             //
    03451
    03452             Irp->IoStatus.Status = STATUS_IO_REPARSE_TAG_NOT_HANDLED;
    03453         }
    03454     }
    03455
    03456     //
    03457     // Check the auxiliary buffer pointer in the packet and if a buffer was
    03458     // allocated, deallocate it now.  Note that this buffer must be freed
    03459     // here since the pointer is overlayed with the APC that will be used
    03460     // to get to the requesting thread's context.
    03461     //
    03462
    03463     if (Irp->Tail.Overlay.AuxiliaryBuffer) {
    03464         ExFreePool( Irp->Tail.Overlay.AuxiliaryBuffer );
    03465         Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
    03466     }
    03467
    03468     //
    03469     // Check to see if this is paging I/O or a close operation.  If either,
    03470     // then special processing must be performed.  The reasons that special
    03471     // processing must be performed is different based on the type of
    03472     // operation being performed.  The biggest reasons for special processing
    03473     // on paging operations are that using a special kernel APC for an in-
    03474     // page operation cannot work since the special kernel APC can incur
    03475     // another pagefault.  Likewise, all paging I/O uses MDLs that belong
    03476     // to the memory manager, not the I/O system.
    03477     //
    03478     // Close operations are special because the close may have been invoked
    03479     // because of a special kernel APC (some IRP was completed which caused
    03480     // the reference count on the object to become zero while in the I/O
    03481     // system's special kernel APC routine).  Therefore, a special kernel APC
    03482     // cannot be used since it cannot execute until the close APC finishes.
    03483     //
    03484     // The special steps are as follows for a synchronous paging operation
    03485     // and close are:
    03486     //
    03487     //     1.  Copy the I/O status block (it is in SVAS, nonpaged).
    03488     //     2.  Signal the event
    03489     //     3.  If paging I/O, deallocate the IRP
    03490     //
    03491     // The special steps taken for asynchronous paging operations (out-pages)
    03492     // are as follows:
    03493     //
    03494     //     1.  Initialize a special kernel APC just for page writes.
    03495     //     1.  Queue the special kernel APC.
    03496     //
    03497     // It should also be noted that the logic for completing a Mount request
    03498     // operation is exactly the same as a Page Read.  No assumptions should be
    03499     // made here about this being a Page Read operation w/o carefully checking
    03500     // to ensure that they are also true for a Mount.  That is:
    03501     //
    03502     //     IRP_PAGING_IO  and  IRP_MOUNT_COMPLETION
    03503     //
    03504     // are the same flag in the IRP.
    03505     //
    03506     // Also note that the last time the IRP is touched for a close operation
    03507     // must be just before the event is set to the signaled state.  Once this
    03508     // occurs, the IRP can be deallocated by the thread waiting for the event.
    03509     //
    03510
    03511     if (Irp->Flags & (IRP_PAGING_IO | IRP_CLOSE_OPERATION)) {
    03512         if (Irp->Flags & (IRP_SYNCHRONOUS_PAGING_IO | IRP_CLOSE_OPERATION)) {
    03513             ULONG flags;
    03514
    03515             flags = Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO;
    03516             *Irp->UserIosb = Irp->IoStatus;
    03517             (VOID) KeSetEvent( Irp->UserEvent, PriorityBoost, FALSE );
    03518             if (flags) {
    03519                 IoFreeIrp( Irp );
    03520             }
    03521         } else {
    03522             thread = Irp->Tail.Overlay.Thread;
    03523             KeInitializeApc( &Irp->Tail.Apc,
    03524                              &thread->Tcb,
    03525                              Irp->ApcEnvironment,
    03526                              IopCompletePageWrite,
    03527                              (PKRUNDOWN_ROUTINE) NULL,
    03528                              (PKNORMAL_ROUTINE) NULL,
    03529                              KernelMode,
    03530                              (PVOID) NULL );
    03531             (VOID) KeInsertQueueApc( &Irp->Tail.Apc,
    03532                                      (PVOID) NULL,
    03533                                      (PVOID) NULL,
    03534                                      PriorityBoost );
    03535         }
    03536         return;
    03537     }
    03538
    03539     //
    03540     // Check to see whether any pages need to be unlocked.
    03541     //
    03542
    03543     if (Irp->MdlAddress != NULL) {
    03544
    03545         //
    03546         // Unlock any pages that may be described by MDLs.
    03547         //
    03548
    03549         mdl = Irp->MdlAddress;
    03550         while (mdl != NULL) {
    03551             MmUnlockPages( mdl );
    03552             mdl = mdl->Next;
    03553         }
    03554     }
    03555
    03556     //
    03557     // Make a final check here to determine whether or not this is a
    03558     // synchronous I/O operation that is being completed in the context
    03559     // of the original requestor.  If so, then an optimal path through
    03560     // I/O completion can be taken.
    03561     //
    03562
    03563     if (Irp->Flags & IRP_DEFER_IO_COMPLETION && !Irp->PendingReturned) {
    03564
    03565         if ((Irp->IoStatus.Status == STATUS_REPARSE )  &&
    03566             (Irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) {
    03567
    03568             //
    03569             // For name junctions we reinstate the address of the appropriate
    03570             // buffer. It is freed in parse.c
    03571             //
    03572
    03573             Irp->Tail.Overlay.AuxiliaryBuffer = saveAuxiliaryPointer;
    03574         }
    03575
    03576         return;
    03577     }
    03578
    03579     //
    03580     // Finally, initialize the IRP as an APC structure and queue the special
    03581     // kernel APC to the target thread.
    03582     //
    03583
    03584     thread = Irp->Tail.Overlay.Thread;
    03585     fileObject = Irp->Tail.Overlay.OriginalFileObject;
    03586
    03587     if (!Irp->Cancel) {
    03588
    03589         KeInitializeApc( &Irp->Tail.Apc,
    03590                          &thread->Tcb,
    03591                          Irp->ApcEnvironment,
    03592                          IopCompleteRequest,
    03593                          IopAbortRequest,
    03594                          (PKNORMAL_ROUTINE) NULL,
    03595                          KernelMode,
    03596                          (PVOID) NULL );
    03597
    03598         (VOID) KeInsertQueueApc( &Irp->Tail.Apc,
    03599                                  fileObject,
    03600                                  (PVOID) saveAuxiliaryPointer,
    03601                                  PriorityBoost );
    03602     } else {
    03603
    03604         //
    03605         // This request has been cancelled.  Ensure that access to the thread
    03606         // is synchronized, otherwise it may go away while attempting to get
    03607         // through the remainder of completion for this request.  This happens
    03608         // when the thread times out waiting for the request to be completed
    03609         // once it has been cancelled.
    03610         //
    03611         // Note that it is safe to capture the thread pointer above, w/o having
    03612         // the lock because the cancel flag was not set at that point, and
    03613         // the code that disassociates IRPs must set the flag before looking to
    03614         // see whether or not the packet has been completed, and this packet
    03615         // will appear to be completed because it no longer belongs to a driver.
    03616         //
    03617
    03618         ExAcquireSpinLock( &IopCompletionLock, &irql );
    03619
    03620         thread = Irp->Tail.Overlay.Thread;
    03621
    03622         if (thread) {
    03623
    03624             KeInitializeApc( &Irp->Tail.Apc,
    03625                              &thread->Tcb,
    03626                              Irp->ApcEnvironment,
    03627                              IopCompleteRequest,
    03628                              IopAbortRequest,
    03629                              (PKNORMAL_ROUTINE) NULL,
    03630                              KernelMode,
    03631                              (PVOID) NULL );
    03632
    03633             (VOID) KeInsertQueueApc( &Irp->Tail.Apc,
    03634                                      fileObject,
    03635                                      (PVOID) saveAuxiliaryPointer,
    03636                                      PriorityBoost );
    03637
    03638             ExReleaseSpinLock( &IopCompletionLock, irql );
    03639
    03640         } else {
    03641
    03642             //
    03643             // This request has been aborted from completing in the caller's
    03644             // thread.  This can only occur if the packet was cancelled, and
    03645             // the driver did not complete the request, so it was timed out.
    03646             // Attempt to drop things on the floor, since the originating thread
    03647             // has probably exited at this point.
    03648             //
    03649
    03650             ExReleaseSpinLock( &IopCompletionLock, irql );
    03651
    03652             ASSERT( Irp->Cancel );
    03653
    03654             //
    03655             // Drop the IRP on the floor.
    03656             //
    03657
    03658             IopDropIrp( Irp, fileObject );
    03659
    03660         }
    03661     }
    03662 }

VOID IopFreeIrp | ( | IN PIRP | Irp | ) |

Definition at line 6641 of file iosubs.c.

References _IRP::AllocationFlags, ASSERT, _IRP::CurrentLocation, _GENERAL_LOOKASIDE::Depth, ExFreePool(), ExInterlockedPushEntrySList(), ExQueryDepthSList, ExReturnPoolQuota(), _GENERAL_LOOKASIDE::FreeMisses, IO_TYPE_IRP, IopLookasideIrpFloat, IopLookasideIrpLimit, Irp, IRP_ALLOCATED_FIXED_SIZE, IRP_ALLOCATED_MUST_SUCCEED, IRP_LOOKASIDE_ALLOCATION, IRP_QUOTA_CHARGED, KeBugCheckEx(), KeGetCurrentPrcb, _NPAGED_LOOKASIDE_LIST::L, _GENERAL_LOOKASIDE::ListHead, _NPAGED_LOOKASIDE_LIST::Lock, LookasideLargeIrpList, LookasideSmallIrpList, PP_NPAGED_LOOKASIDE_NUMBER, _IRP::StackCount, _GENERAL_LOOKASIDE::TotalFrees, and _IRP::Type.

Referenced by IopSetIoRoutines(), and IovFreeIrpPrivate().

    06647                    :
    06648
    06649     This routine deallocates the specified I/O Request Packet.
    06650
    06651 Arguments:
    06652
    06653     Irp - I/O Request Packet to deallocate.
    06654
    06655 Return Value:
    06656
    06657     None.
    06658
    06659 --*/
    06660
    06661 {
    06662     PNPAGED_LOOKASIDE_LIST lookasideList;
    06663     PP_NPAGED_LOOKASIDE_NUMBER number;
    06664     PKPRCB prcb;
    06665
    06666     //
    06667     // Ensure that the data structure being freed is really an IRP.
    06668     //
    06669
    06670     ASSERT( Irp->Type == IO_TYPE_IRP );
    06671
    06672     if (Irp->Type != IO_TYPE_IRP) {
    06673         KeBugCheckEx( MULTIPLE_IRP_COMPLETE_REQUESTS, (ULONG_PTR) Irp, __LINE__, 0, 0 );
    06674     }
    06675
    06676
    06677     ASSERT(IsListEmpty(&(Irp)->ThreadListEntry));
    06678     Irp->Type = 0;
    06679
    06680     //
    06681     // Ensure that all of the owners of the IRP have at least been notified
    06682     // that the request is going away.
    06683     //
    06684
    06685     ASSERT( Irp->CurrentLocation >= Irp->StackCount );
    06686
    06687     //
    06688     // Deallocate the IRP.
    06689     //
    06690
    06691     if (Irp->AllocationFlags & IRP_LOOKASIDE_ALLOCATION) {
    06692         Irp->AllocationFlags ^= IRP_LOOKASIDE_ALLOCATION;
    06693         InterlockedDecrement( &IopLookasideIrpFloat );
    06694     }
    06695     if (!(Irp->AllocationFlags & IRP_ALLOCATED_FIXED_SIZE) ||
    06696         (Irp->AllocationFlags & IRP_ALLOCATED_MUST_SUCCEED) ||
    06697         (IopLookasideIrpFloat >= IopLookasideIrpLimit)) {
    06698         ExFreePool( Irp );
    06699
    06700     } else {
    06701         number = LookasideSmallIrpList;
    06702         if (Irp->StackCount != 1) {
    06703             number = LookasideLargeIrpList;
    06704         }
    06705
    06706         prcb = KeGetCurrentPrcb();
    06707         lookasideList = prcb->PPLookasideList[number].P;
    06708         lookasideList->L.TotalFrees += 1;
    06709         if ( ExQueryDepthSList( &lookasideList->L.ListHead ) >= lookasideList->L.Depth ) {
    06710             lookasideList->L.FreeMisses += 1;
    06711             lookasideList = prcb->PPLookasideList[number].L;
    06712             lookasideList->L.TotalFrees += 1;
    06713             if (ExQueryDepthSList( &lookasideList->L.ListHead ) >= lookasideList->L.Depth) {
    06714                 lookasideList->L.FreeMisses += 1;
    06715                 ExFreePool( Irp );
    06716
    06717             } else {
    06718                 if (Irp->AllocationFlags & IRP_QUOTA_CHARGED) {
    06719                     Irp->AllocationFlags ^= IRP_QUOTA_CHARGED;
    06720                     ExReturnPoolQuota( Irp );
    06721                 }
    06722
    06723                 ExInterlockedPushEntrySList( &lookasideList->L.ListHead,
    06724                                              (PSINGLE_LIST_ENTRY) Irp,
    06725                                              &lookasideList->Lock );
    06726             }
    06727
    06728         } else {
    06729             if (Irp->AllocationFlags & IRP_QUOTA_CHARGED) {
    06730                 Irp->AllocationFlags ^= IRP_QUOTA_CHARGED;
    06731                 ExReturnPoolQuota( Irp );
    06732             }
    06733
    06734             ExInterlockedPushEntrySList( &lookasideList->L.ListHead,
    06735                                          (PSINGLE_LIST_ENTRY) Irp,
    06736                                          &lookasideList->Lock );
    06737         }
    06738     }
    06739
    06740     return;
    06741 }

VOID IopFreeIrpAndMdls | ( | IN PIRP | Irp | ) |

Definition at line 2029 of file internal.c.

References IoFreeIrp(), IoFreeMdl(), Irp, _IRP::MdlAddress, _MDL::Next, and NULL.

    02035                    :
    02036
    02037     This routine frees the specified I/O Request Packet and all of its Memory
    02038     Descriptor Lists.
    02039
    02040 Arguments:
    02041
    02042     Irp - Pointer to the I/O Request Packet to be freed.
    02043
    02044 Return Value:
    02045
    02046     None.
    02047
    02048 --*/
    02049
    02050 {
    02051     PMDL mdl;
    02052     PMDL nextMdl;
    02053
    02054     //
    02055     // If there are any MDLs that need to be freed, free them now.
    02056     //
    02057
    02058     for (mdl = Irp->MdlAddress; mdl != (PMDL) NULL; mdl = nextMdl) {
    02059         nextMdl = mdl->Next;
    02060         IoFreeMdl( mdl );
    02061     }
    02062
    02063     //
    02064     // Free the IRP.
    02065     //
    02066
    02067     IoFreeIrp( Irp );
    02068     return;
    02069 }

PDEVICE_OBJECT IopGetDeviceAttachmentBase | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 3919 of file internal.c.

References _DEVOBJ_EXTENSION::AttachedTo, _DEVICE_OBJECT::DeviceObjectExtension, and NULL.

Referenced by IopCompleteUnloadOrDelete(), IopGetDeviceAttachmentBaseRef(), and IopGetDevicePDO().

    03925                    :
    03926
    03927     This routine returns the lowest level device object associated with
    03928     the specified device.
    03929
    03930 Arguments:
    03931
    03932     DeviceObject - Supplies a pointer to the device for which the bottom of
    03933         attachment chain is to be found.
    03934
    03935 Return Value:
    03936
    03937     The function value is a reference to the lowest level device attached
    03938     to the specified device.  If the supplied device object is that device
    03939     object, then a pointer to it is returned.
    03940
    03941     N.B. Caller must own the IopDatabaseLock.
    03942
    03943 --*/
    03944
    03945 {
    03946     PDEVICE_OBJECT baseDeviceObject;
    03947     PDEVOBJ_EXTENSION deviceExtension;
    03948
    03949     //
    03950     // Descend down the attachment chain until we find a device object
    03951     // that isn't attached to anything else.
    03952     //
    03953
    03954     baseDeviceObject = DeviceObject;
    03955     deviceExtension = baseDeviceObject->DeviceObjectExtension;
    03956     while (deviceExtension->AttachedTo != NULL) {
    03957
    03958         baseDeviceObject = deviceExtension->AttachedTo;
    03959         deviceExtension = baseDeviceObject->DeviceObjectExtension;
    03960     }
    03961
    03962     return baseDeviceObject;
    03963 }

PDEVICE_OBJECT IopGetDeviceAttachmentBaseRef | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 3967 of file internal.c.

References IopDatabaseLock, IopGetDeviceAttachmentBase(), and ObReferenceObject.

    03973                    :
    03974
    03975     This routine returns the lowest level device object associated with
    03976     the specified device.
    03977
    03978 Arguments:
    03979
    03980     DeviceObject - Supplies a pointer to the device for which the bottom of
    03981         attachment chain is to be found.
    03982
    03983 Return Value:
    03984
    03985     The function value is a reference to the lowest level device attached
    03986     to the specified device.  If the supplied device object is that device
    03987     object, then a pointer to it is returned.
    03988
    03989     A reference is taken on the returned device object.  It is the
    03990     responsibility of the caller to release it.
    03991
    03992 --*/
    03993
    03994 {
    03995     PDEVICE_OBJECT baseDeviceObject;
    03996     KIRQL irql;
    03997
    03998     //
    03999     // Any examination of attachment chain linkage must be done with
    04000     // IopDatabaseLock taken.
    04001     //
    04002
    04003     ExAcquireSpinLock( &IopDatabaseLock, &irql );
    04004
    04005     //
    04006     // Find the base of the attachment chain.
    04007     //
    04008
    04009     baseDeviceObject = IopGetDeviceAttachmentBase( DeviceObject );
    04010
    04011     //
    04012     // Reference the device object before releasing the database lock.
    04013     //
    04014
    04015     ObReferenceObject( baseDeviceObject );
    04016     ExReleaseSpinLock( &IopDatabaseLock, irql );
    04017
    04018     return baseDeviceObject;
    04019 }

NTSTATUS IopGetDriverNameFromKeyNode | ( | IN HANDLE | KeyHandle,
|  | OUT PUNICODE_STRING | DriverName
| ) |

Definition at line 2072 of file internal.c.

References ExAllocatePool, ExFreePool(), IopGetRegistryValue(), L, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), and USHORT.

Referenced by IopCallDriverAddDeviceQueryRoutine(), IopInitializeBootDrivers(), IopInitializeSystemDrivers(), IopLoadBootFilterDriver(), IopLoadDriver(), and NtUnloadDriver().

    02079                    :
    02080
    02081     Given a handle to a driver service list key in the registry, return the
    02082     name that represents the Object Manager name space string that should
    02083     be used to locate/create the driver object.
    02084
    02085 Arguments:
    02086
    02087     KeyHandle - Supplies a handle to driver service entry in the registry.
    02088
    02089     DriverName - Supplies a Unicode string descriptor variable in which the
    02090         name of the driver is returned.
    02091
    02092 Return Value:
    02093
    02094     The function value is the final status of the operation.
    02095
    02096 --*/
    02097
    02098 {
    02099     PKEY_VALUE_FULL_INFORMATION keyValueInformation;
    02100     PKEY_BASIC_INFORMATION keyBasicInformation;
    02101     ULONG keyBasicLength;
    02102     NTSTATUS status;
    02103
    02104     PAGED_CODE();
    02105
    02106     //
    02107     // Get the optional object name for this driver from the value for this
    02108     // key.  If one exists, then its name overrides the default name of the
    02109     // driver.
    02110     //
    02111
    02112     status = IopGetRegistryValue( KeyHandle,
    02113                                   L"ObjectName",
    02114                                   &keyValueInformation );
    02115
    02116     if (NT_SUCCESS( status )) {
    02117
    02118         PWSTR src, dst;
    02119         ULONG i;
    02120
    02121         //
    02122         // The driver entry specifies an object name.  This overrides the
    02123         // default name for the driver.  Use this name to open the driver
    02124         // object.
    02125         //
    02126
    02127         if (!keyValueInformation->DataLength) {
    02128             ExFreePool( keyValueInformation );
    02129             return STATUS_ILL_FORMED_SERVICE_ENTRY;
    02130         }
    02131
    02132         DriverName->Length = (USHORT) (keyValueInformation->DataLength - sizeof( WCHAR ));
    02133         DriverName->MaximumLength = (USHORT) keyValueInformation->DataLength;
    02134
    02135         src = (PWSTR) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset);
    02136         dst = (PWSTR) keyValueInformation;
    02137         for (i = DriverName->Length; i; i--) {
    02138             *dst++ = *src++;
    02139         }
    02140
    02141         DriverName->Buffer = (PWSTR) keyValueInformation;
    02142
    02143     } else {
    02144
    02145         PULONG driverType;
    02146         PWSTR baseObjectName;
    02147         UNICODE_STRING remainderName;
    02148
    02149         //
    02150         // The driver node does not specify an object name, so determine
    02151         // what the default name for the driver object should be based on
    02152         // the information in the key.
    02153         //
    02154
    02155         status = IopGetRegistryValue( KeyHandle,
    02156                                       L"Type",
    02157                                       &keyValueInformation );
    02158         if (!NT_SUCCESS( status ) || !keyValueInformation->DataLength) {
    02159
    02160             //
    02161             // There must be some type of "Type" associated with this driver,
    02162             // either DRIVER or FILE_SYSTEM.  Otherwise, this node is ill-
    02163             // formed.
    02164             //
    02165
    02166             if (NT_SUCCESS( status )) {
    02167                 ExFreePool( keyValueInformation );
    02168             }
    02169
    02170             return STATUS_ILL_FORMED_SERVICE_ENTRY;
    02171         }
    02172
    02173         //
    02174         // Now determine whether the type of this entry is a driver or a
    02175         // file system.  Begin by assuming that it is a device driver.
    02176         //
    02177
    02178         baseObjectName = L"\\Driver\\";
    02179         DriverName->Length = 8*2;
    02180
    02181         driverType = (PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset);
    02182
    02183         if (*driverType == FileSystemType ||
    02184             *driverType == RecognizerType) {
    02185             baseObjectName = L"\\FileSystem\\";
    02186             DriverName->Length = 12*2;
    02187         }
    02188
    02189         //
    02190         // Get the name of the key that is being used to describe this
    02191         // driver.  This will return just the last component of the name
    02192         // string, which can be used to formulate the name of the driver.
    02193         //
    02194
    02195         status = ZwQueryKey( KeyHandle,
    02196                              KeyBasicInformation,
    02197                              (PVOID) NULL,
    02198                              0,
    02199                              &keyBasicLength );
    02200
    02201         keyBasicInformation = ExAllocatePool( NonPagedPool, keyBasicLength );
    02202         if (!keyBasicInformation) {
    02203             ExFreePool( keyValueInformation );
    02204             return STATUS_INSUFFICIENT_RESOURCES;
    02205         }
    02206
    02207         status = ZwQueryKey( KeyHandle,
    02208                              KeyBasicInformation,
    02209                              keyBasicInformation,
    02210                              keyBasicLength,
    02211                              &keyBasicLength );
    02212         if (!NT_SUCCESS( status )) {
    02213             ExFreePool( keyBasicInformation );
    02214             ExFreePool( keyValueInformation );
    02215             return status;
    02216         }
    02217
    02218         //
    02219         // Allocate a buffer from pool that is large enough to contain the
    02220         // entire name string of the driver object.
    02221         //
    02222
    02223         DriverName->MaximumLength = (USHORT) (DriverName->Length + keyBasicInformation->NameLength);
    02224         DriverName->Buffer = ExAllocatePool( NonPagedPool,
    02225                                             DriverName->MaximumLength );
    02226         if (!DriverName->Buffer) {
    02227             ExFreePool( keyBasicInformation );
    02228             ExFreePool( keyValueInformation );
    02229             return STATUS_INSUFFICIENT_RESOURCES;
    02230         }
    02231
    02232         //
    02233         // Now form the name of the object to be opened.
    02234         //
    02235
    02236         DriverName->Length = 0;
    02237         RtlAppendUnicodeToString( DriverName, baseObjectName );
    02238         remainderName.Length = (USHORT) keyBasicInformation->NameLength;
    02239         remainderName.MaximumLength = remainderName.Length;
    02240         remainderName.Buffer = &keyBasicInformation->Name[0];
    02241         RtlAppendUnicodeStringToString( DriverName, &remainderName );
    02242         ExFreePool( keyBasicInformation );
    02243         ExFreePool( keyValueInformation );
    02244     }
    02245
    02246     //
    02247     // Finally, simply return to the caller with the name filled in.  Note
    02248     // that the caller must free the buffer pointed to by the Buffer field
    02249     // of the Unicode string descriptor.
    02250     //
    02251
    02252     return STATUS_SUCCESS;
    02253 }

ULONG IopGetDumpControlBlockCheck | ( | IN PDUMP_CONTROL_BLOCK | Dcb | ) |

Definition at line 1062 of file dumpctl.c.

References DUMP_CONTROL_BLOCK, NULL, PDUMP_STACK_CONTEXT, PDUMP_STACK_IMAGE, and PoSimpleCheck().

Referenced by IopCompleteDumpInitialization(), and IoWriteCrashDump().

    01067                    :
    01068
    01069     Return the current checksum total for the Dcb
    01070
    01071 Arguments:
    01072
    01073     DumpStack           - Dump driver stack to checksum
    01074
    01075 Return Value:
    01076
    01077     Checksum value
    01078
    01079 --*/
    01080 {
    01081     ULONG                   Check;
    01082     PLIST_ENTRY             Link;
    01083     PDUMP_STACK_IMAGE       DumpImage;
    01084     PMAPPED_ADDRESS         MappedAddress;
    01085     PDUMP_STACK_CONTEXT     DumpStack;
    01086
    01087
    01088     //
    01089     // Check the DCB, memory descriptor array, and the FileDescriptorArray
    01090     //
    01091
    01092     Check = PoSimpleCheck(0, Dcb, sizeof(DUMP_CONTROL_BLOCK));
    01093     Check = PoSimpleCheck(
    01094                 Check,
    01095                 Dcb->MemoryDescriptor,
    01096                 Dcb->MemoryDescriptorLength
    01097                 );
    01098
    01099     Check = PoSimpleCheck(Check, Dcb->FileDescriptorArray, Dcb->FileDescriptorSize);
    01100
    01101     DumpStack = Dcb->DumpStack;
    01102     if (DumpStack) {
    01103
    01104         //
    01105         // Include the dump stack context structure, and dump driver images
    01106         //
    01107
    01108         Check = PoSimpleCheck(Check, DumpStack, sizeof(DUMP_STACK_CONTEXT));
    01109         Check = PoSimpleCheck(Check, DumpStack->DumpPointers, DumpStack->PointersLength);
    01110
    01111         for (Link = DumpStack->DriverList.Flink;
    01112              Link != &DumpStack->DriverList;
    01113              Link = Link->Flink) {
    01114
    01115             DumpImage = CONTAINING_RECORD(Link, DUMP_STACK_IMAGE, Link);
    01116             Check = PoSimpleCheck(Check, DumpImage, sizeof(DUMP_STACK_IMAGE));
    01117             Check = PoSimpleCheck(Check, DumpImage->ImageBase, DumpImage->SizeOfImage);
    01118         }
    01119
    01120         //
    01121         // Include the mapped addresses
    01122         //
    01123         // If this is non-null it is treated as a PMAPPED_ADDRESS * (see scsiport and atdisk)
    01124         //
    01125         if (DumpStack->Init.MappedRegisterBase != NULL) {
    01126             MappedAddress = *(PMAPPED_ADDRESS *)DumpStack->Init.MappedRegisterBase;
    01127         } else {
    01128             MappedAddress = NULL;
    01129         }
    01130
    01131         while (MappedAddress) {
    01132             Check = PoSimpleCheck (Check, MappedAddress, sizeof(MAPPED_ADDRESS));
    01133             MappedAddress = MappedAddress->NextMappedAddress;
    01134         }
    01135     }
    01136
    01137     return Check;
    01138 }

NTSTATUS IopGetFileName | ( | IN PFILE_OBJECT | FileObject,
|  | IN ULONG | Length,
|  | OUT PVOID | FileInformation,
|  | OUT PULONG | ReturnedLength
| ) |

Definition at line 2256 of file internal.c.

References _IRP::AssociatedIrp, Executive, FALSE, _IO_STACK_LOCATION::FileObject, _IRP::Flags, IoAllocateIrp(), IoCallDriver, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAllocateIrpCleanup(), IopQueueThreadIrp, IRP_BUFFERED_IO, IRP_MJ_QUERY_INFORMATION, IRP_OB_QUERY_NAME, IRP_SYNCHRONOUS_API, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, NTSTATUS(), NULL, ObReferenceObject, _IRP::Overlay, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PsGetCurrentThread, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, _IRP::Tail, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IopQueryName().

    02265                    :
    02266
    02267     This routine is invoked to asynchronously obtain the name of a file object
    02268     when the file was opened for synchronous I/O, and the previous mode of the
    02269     caller was kernel mode, and the query was done through the Object Manager.
    02270     In this case, the situation is likely that the Lazy Writer has incurred a
    02271     write error, and it is attempting to obtain the name of the file so that it
    02272     can output a popup.  In doing so, a deadlock can occur because another
    02273     thread has locked the file object synchronous I/O lock.  Hence, this routine
    02274     obtains the name of the file w/o acquiring that lock.
    02275
    02276 Arguments:
    02277
    02278     FileObject - A pointer to the file object whose name is to be queried.
    02279
    02280     Length - Supplies the length of the buffer to receive the name.
    02281
    02282     FileInformation - A pointer to the buffer to receive the name.
    02283
    02284     ReturnedLength - A variable to receive the length of the name returned.
    02285
    02286 Return Value:
    02287
    02288     The status returned is the final completion status of the operation.
    02289
    02290 --*/
    02291
    02292 {
    02293
    02294     PIRP irp;
    02295     NTSTATUS status;
    02296     PDEVICE_OBJECT deviceObject;
    02297     KEVENT event;
    02298     PIO_STACK_LOCATION irpSp;
    02299     IO_STATUS_BLOCK localIoStatus;
    02300
    02301     PAGED_CODE();
    02302
    02303     //
    02304     // Reference the file object here so that no special checks need be made
    02305     // in I/O completion to determine whether or not to dereference the file
    02306     // object.
    02307     //
    02308
    02309     ObReferenceObject( FileObject );
    02310
    02311     //
    02312     // Initialize an event that will be used to synchronize the completion of
    02313     // the query operation.  Note that this is the only way to synchronize this
    02314     // since the file object itself cannot be used since it was opened for
    02315     // synchronous I/O and may be busy.
    02316     //
    02317
    02318     KeInitializeEvent( &event, SynchronizationEvent, FALSE );
    02319
    02320     //
    02321     // Get the address of the target device object.
    02322     //
    02323
    02324     deviceObject = IoGetRelatedDeviceObject( FileObject );
    02325
    02326     //
    02327     // Allocate and initialize the I/O Request Packet (IRP) for this operation.
    02328     //
    02329
    02330     irp = IoAllocateIrp( deviceObject->StackSize, FALSE );
    02331     if (!irp) {
    02332
    02333         //
    02334         // An IRP could not be allocated.  Cleanup and return an appropriate
    02335         // error status code.
    02336         //
    02337
    02338         IopAllocateIrpCleanup( FileObject, (PKEVENT) NULL );
    02339         return STATUS_INSUFFICIENT_RESOURCES;
    02340     }
    02341
    02342     irp->Tail.Overlay.OriginalFileObject = FileObject;
    02343     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    02344     irp->RequestorMode = KernelMode;
    02345
    02346     //
    02347     // Fill in the service independent parameters in the IRP.  Note that the
    02348     // setting of the special query name flag in the packet guarantees that the
    02349     // standard completion for a synchronous file object will not occur because
    02350     // this flag communicates to the I/O completion that it should not do so.
    02351     //
    02352
    02353     irp->UserEvent = &event;
    02354     irp->Flags = IRP_SYNCHRONOUS_API | IRP_OB_QUERY_NAME;
    02355     irp->UserIosb = &localIoStatus;
    02356     irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    02357
    02358     //
    02359     // Get a pointer to the stack location for the first driver.  This will be
    02360     // used to pass the original function codes and parameters.
    02361     //
    02362
    02363     irpSp = IoGetNextIrpStackLocation( irp );
    02364     irpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION;
    02365     irpSp->FileObject = FileObject;
    02366
    02367     //
    02368     // Set the system buffer address to the address of the caller's buffer and
    02369     // set the flags so that the buffer is not deallocated.
    02370     //
    02371
    02372     irp->AssociatedIrp.SystemBuffer = FileInformation;
    02373     irp->Flags |= IRP_BUFFERED_IO;
    02374
    02375     //
    02376     // Copy the caller's parameters to the service-specific portion of the
    02377     // IRP.
    02378     //
    02379
    02380     irpSp->Parameters.QueryFile.Length = Length;
    02381     irpSp->Parameters.QueryFile.FileInformationClass = FileNameInformation;
    02382
    02383     //
    02384     // Insert the packet at the head of the IRP list for the thread.
    02385     //
    02386
    02387     IopQueueThreadIrp( irp );
    02388
    02389     //
    02390     // Now simply invoke the driver at its dispatch entry with the IRP.
    02391     //
    02392
    02393     status = IoCallDriver( deviceObject, irp );
    02394
    02395     //
    02396     // Now get the final status of the operation once the request completes
    02397     // and return the length of the buffer written.
    02398     //
    02399
    02400     if (status == STATUS_PENDING) {
    02401         (VOID) KeWaitForSingleObject( &event,
    02402                                       Executive,
    02403                                       KernelMode,
    02404                                       FALSE,
    02405                                       (PLARGE_INTEGER) NULL );
    02406         status = localIoStatus.Status;
    02407     }
    02408
    02409     *ReturnedLength = (ULONG) localIoStatus.Information;
    02410     return status;
    02411 }

BOOLEAN IopGetMountFlag | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 2414 of file internal.c.

References FALSE, IopVpbSpinLock, TRUE, and VPB_MOUNTED.

Referenced by NtQueryVolumeInformationFile().

    02420                    :
    02421
    02422     This routine is invoked to determine whether or not the specified device
    02423     is mounted.
    02424
    02425 Arguments:
    02426
    02427     DeviceObject - Supplies a pointer to the device object for which the mount
    02428         flag is tested.
    02429
    02430 Return Value:
    02431
    02432     The function value is TRUE if the specified device is mounted, otherwise
    02433     FALSE.
    02434
    02435
    02436 --*/
    02437
    02438 {
    02439     KIRQL irql;
    02440     BOOLEAN deviceMounted = FALSE;
    02441
    02442     //
    02443     // Check to see whether or not the device is mounted.  Note that the caller
    02444     // has probably already looked to see whether or not the device has a VPB
    02445     // outside of owning the lock, so simply get the lock and check it again
    02446     // to start with, rather than checking to see whether or not the device
    02447     // still has a VPB without holding the lock.
    02448     //
    02449
    02450     ExAcquireFastLock( &IopVpbSpinLock, &irql );
    02451     if (DeviceObject->Vpb) {
    02452         if (DeviceObject->Vpb->Flags & VPB_MOUNTED) {
    02453             deviceMounted = TRUE;
    02454         }
    02455     }
    02456     ExReleaseFastLock( &IopVpbSpinLock, irql );
    02457
    02458     return deviceMounted;
    02459 }

NTSTATUS IopGetRegistryKeyInformation | ( | IN HANDLE | KeyHandle,
|  | OUT PKEY_FULL_INFORMATION * | Information
| ) |

Definition at line 2462 of file internal.c.

References ExAllocatePool, ExFreePool(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopUnregisterDeviceInterface(), pIoQueryBusDescription(), and pIoQueryDeviceDescription().

    02469                    :
    02470
    02471     This routine is invoked to retrieve the full key information for a
    02472     registry key.  This is done by querying the full key information
    02473     of the key with a zero-length buffer to determine the size of the data,
    02474     and then allocating a buffer and actually querying the data into the buffer.
    02475
    02476     It is the responsibility of the caller to free the buffer.
    02477
    02478 Arguments:
    02479
    02480     KeyHandle - Supplies the key handle whose full key information is to
    02481         be queried
    02482
    02483     Information - Returns a pointer to the allocated data buffer.
    02484
    02485 Return Value:
    02486
    02487     The function value is the final status of the query operation.
    02488
    02489 --*/
    02490
    02491 {
    02492     NTSTATUS status;
    02493     PKEY_FULL_INFORMATION infoBuffer;
    02494     ULONG keyInfoLength;
    02495
    02496     PAGED_CODE();
    02497
    02498     //
    02499     // Figure out how big the data value is so that a buffer of the
    02500     // appropriate size can be allocated.
    02501     //
    02502
    02503     status = ZwQueryKey( KeyHandle,
    02504                          KeyFullInformation,
    02505                          (PVOID) NULL,
    02506                          0,
    02507                          &keyInfoLength );
    02508     if (status != STATUS_BUFFER_OVERFLOW &&
    02509         status != STATUS_BUFFER_TOO_SMALL) {
    02510         return status;
    02511     }
    02512
    02513     //
    02514     // Allocate a buffer large enough to contain the entire key data.
    02515     //
    02516
    02517     infoBuffer = ExAllocatePool( NonPagedPool, keyInfoLength );
    02518     if (!infoBuffer) {
    02519         return STATUS_INSUFFICIENT_RESOURCES;
    02520     }
    02521
    02522     //
    02523     // Query the full key data for the key.
    02524     //
    02525
    02526     status = ZwQueryKey( KeyHandle,
    02527                          KeyFullInformation,
    02528                          infoBuffer,
    02529                          keyInfoLength,
    02530                          &keyInfoLength );
    02531     if (!NT_SUCCESS( status )) {
    02532         ExFreePool( infoBuffer );
    02533         return status;
    02534     }
    02535
    02536     //
    02537     // Everything worked, so simply return the address of the allocated
    02538     // buffer to the caller, who is now responsible for freeing it.
    02539     //
    02540
    02541     *Information = infoBuffer;
    02542     return STATUS_SUCCESS;
    02543 }

NTSTATUS IopGetRegistryValue | ( | IN HANDLE | KeyHandle,
|  | IN PWSTR | ValueName,
|  | OUT PKEY_VALUE_FULL_INFORMATION * | Information
| ) |

Definition at line 2546 of file internal.c.

    02554                    :
    02555
    02556     This routine is invoked to retrieve the data for a registry key's value.
    02557     This is done by querying the value of the key with a zero-length buffer
    02558     to determine the size of the value, and then allocating a buffer and
    02559     actually querying the value into the buffer.
    02560
    02561     It is the responsibility of the caller to free the buffer.
    02562
    02563 Arguments:
    02564
    02565     KeyHandle - Supplies the key handle whose value is to be queried
    02566
    02567     ValueName - Supplies the null-terminated Unicode name of the value.
    02568
    02569     Information - Returns a pointer to the allocated data buffer.
    02570
    02571 Return Value:
    02572
    02573     The function value is the final status of the query operation.
    02574
    02575 --*/
    02576
    02577 {
    02578     UNICODE_STRING unicodeString;
    02579     NTSTATUS status;
    02580     PKEY_VALUE_FULL_INFORMATION infoBuffer;
    02581     ULONG keyValueLength;
    02582
    02583     PAGED_CODE();
    02584
    02585     RtlInitUnicodeString( &unicodeString, ValueName );
    02586
    02587     //
    02588     // Figure out how big the data value is so that a buffer of the
    02589     // appropriate size can be allocated.
    02590     //
    02591
    02592     status = ZwQueryValueKey( KeyHandle,
    02593                               &unicodeString,
    02594                               KeyValueFullInformation,
    02595                               (PVOID) NULL,
    02596                               0,
    02597                               &keyValueLength );
    02598     if (status != STATUS_BUFFER_OVERFLOW &&
    02599         status != STATUS_BUFFER_TOO_SMALL) {
    02600         return status;
    02601     }
    02602
    02603     //
    02604     // Allocate a buffer large enough to contain the entire key data value.
    02605     //
    02606
    02607     infoBuffer = ExAllocatePool( NonPagedPool, keyValueLength );
    02608     if (!infoBuffer) {
    02609         return STATUS_INSUFFICIENT_RESOURCES;
    02610     }
    02611
    02612     //
    02613     // Query the data for the key value.
    02614     //
    02615
    02616     status = ZwQueryValueKey( KeyHandle,
    02617                               &unicodeString,
    02618                               KeyValueFullInformation,
    02619                               infoBuffer,
    02620                               keyValueLength,
    02621                               &keyValueLength );
    02622     if (!NT_SUCCESS( status )) {
    02623         ExFreePool( infoBuffer );
    02624         return status;
    02625     }
    02626
    02627     //
    02628     // Everything worked, so simply return the address of the allocated
    02629     // buffer to the caller, who is now responsible for freeing it.
    02630     //
    02631
    02632     *Information = infoBuffer;
    02633     return STATUS_SUCCESS;
    02634 }

NTSTATUS IopGetRegistryValues | ( | IN HANDLE | KeyHandle,
|  | IN PKEY_VALUE_FULL_INFORMATION * | ValueList
| ) |

Definition at line 2637 of file internal.c.

References IopGetRegistryValue(), L, NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

Referenced by pIoQueryBusDescription(), and pIoQueryDeviceDescription().

    02644                    :
    02645
    02646     This routine is invoked to retrieve the *three* types of data for a
    02647     registry key's.  This is done by calling the IopGetRegistryValue function
    02648     with the three valid key names.
    02649
    02650     It is the responsibility of the caller to free the three buffers.
    02651
    02652 Arguments:
    02653
    02654     KeyHandle - Supplies the key handle whose value is to be queried
    02655
    02656     ValueList - Pointer to a buffer in which the three pointers to the value
    02657         entries will be stored.
    02658
    02659 Return Value:
    02660
    02661     The function value is the final status of the query operation.
    02662
    02663 Note:
    02664
    02665     The values are stored in the order represented by the I/O query device
    02666     data format.
    02667
    02668 --*/
    02669
    02670 {
    02671     NTSTATUS status;
    02672
    02673     PAGED_CODE();
    02674
    02675     //
    02676     // Zero out all entries initially.
    02677     //
    02678
    02679     *ValueList = NULL;
    02680     *(ValueList + 1) = NULL;
    02681     *(ValueList + 2) = NULL;
    02682
    02683     //
    02684     // Get the information for each of the three types of entries available.
    02685     // Each time, check if an internal error occurred; If the object name was
    02686     // not found, it only means not data was present, and this does not
    02687     // constitute an error.
    02688     //
    02689
    02690     status = IopGetRegistryValue( KeyHandle,
    02691                                   L"Identifier",
    02692                                   ValueList );
    02693
    02694     if (!NT_SUCCESS( status ) && (status != STATUS_OBJECT_NAME_NOT_FOUND)) {
    02695         return status;
    02696     }
    02697
    02698     status = IopGetRegistryValue( KeyHandle,
    02699                                   L"Configuration Data",
    02700                                   ++ValueList );
    02701
    02702     if (!NT_SUCCESS( status ) && (status != STATUS_OBJECT_NAME_NOT_FOUND)) {
    02703         return status;
    02704     }
    02705
    02706     status = IopGetRegistryValue( KeyHandle,
    02707                                   L"Component Information",
    02708                                   ++ValueList );
    02709
    02710     if (!NT_SUCCESS( status ) && (status != STATUS_OBJECT_NAME_NOT_FOUND)) {
    02711         return status;
    02712     }
    02713
    02714     return STATUS_SUCCESS;
    02715 }

NTSTATUS IopGetSetObjectId | ( | IN PFILE_OBJECT | FileObject,
|  | IN OUT PVOID | Buffer,
|  | IN ULONG | Length,
|  | IN ULONG | OperationFlags
| ) |

Definition at line 2718 of file internal.c.

References _IRP::AssociatedIrp, Buffer, Executive, FALSE, _IO_STACK_LOCATION::FileObject, _IRP::Flags, IoBuildDeviceIoControlRequest(), IoCallDriver, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_KERNEL_CALL, IRP_SYNCHRONOUS_API, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, ObReferenceObject, PAGED_CODE, _IO_STACK_LOCATION::Parameters, _IRP::Tail, and _IRP::UserBuffer.

Referenced by IopTrackLink().

    02727                    :
    02728
    02729     This routine is invoked to obtain or set the object ID for a file.  If
    02730     one does not exist for the file, then one is created, provided that the
    02731     underlying file system supports object IDs in the first place (query).
    02732
    02733 Arguments:
    02734
    02735     FileObject - Supplies a pointer to the referenced file object whose ID is
    02736         to be returned or set.
    02737
    02738     Buffer - A variable to receive the object ID of the file (query) or that
    02739         contains the object ID that is to be set on the file.
    02740
    02741     Length - The length of the Buffer.
    02742
    02743     Function - The FSCTL to send.
    02744         FSCTL_LMR_GET_LINK_TRACKING_INFORMATION;
    02745         FSCTL_CREATE_OR_GET_OBJECT_ID;
    02746         FSCTL_GET_OBJECT_ID;
    02747         FSCTL_SET_OBJECT_ID_EXTENDED;
    02748         FSCTL_LMR_SET_LINK_TRACKING_INFORMATION;
    02749         FSCTL_SET_OBJECT_ID_EXTENDED;
    02750         FSCTL_SET_OBJECT_ID;
    02751         FSCTL_DELETE_OBJECT_ID;
    02752
    02753 Return Value:
    02754
    02755     The status returned is the final completion status of the operation.
    02756
    02757 --*/
    02758
    02759 {
    02760     IO_STATUS_BLOCK ioStatus;
    02761     NTSTATUS status;
    02762     PIRP irp;
    02763     KEVENT event;
    02764     PIO_STACK_LOCATION irpSp;
    02765     PDEVICE_OBJECT deviceObject;
    02766
    02767     PAGED_CODE();
    02768
    02769     //
    02770     // Initialize the event structure to synchronize completion of the I/O
    02771     // request.
    02772     //
    02773
    02774     KeInitializeEvent( &event,
    02775                        NotificationEvent,
    02776                        FALSE );
    02777
    02778     //
    02779     // Build an I/O Request Packet to be sent to the file system driver to get
    02780     // the object ID.
    02781     //
    02782
    02783     deviceObject = IoGetRelatedDeviceObject( FileObject );
    02784
    02785     irp = IoBuildDeviceIoControlRequest( Function,
    02786                                          deviceObject,
    02787                                          NULL,
    02788                                          0,
    02789                                          NULL,
    02790                                          0,
    02791                                          FALSE,
    02792                                          &event,
    02793                                          &ioStatus );
    02794     if (!irp) {
    02795         return STATUS_INSUFFICIENT_RESOURCES;
    02796     }
    02797
    02798     //
    02799     // Fill in the remainder of the IRP to retrieve the object ID for the
    02800     // file.
    02801     //
    02802
    02803     irp->Flags |= IRP_SYNCHRONOUS_API;
    02804     irp->UserBuffer = Buffer;
    02805     irp->AssociatedIrp.SystemBuffer = Buffer;
    02806     irp->Tail.Overlay.OriginalFileObject = FileObject;
    02807
    02808     irpSp = IoGetNextIrpStackLocation( irp );
    02809     irpSp->FileObject = FileObject;
    02810     irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
    02811     irpSp->MinorFunction = IRP_MN_KERNEL_CALL;
    02812
    02813     if (Function == FSCTL_LMR_GET_LINK_TRACKING_INFORMATION ||
    02814         Function == FSCTL_CREATE_OR_GET_OBJECT_ID ||
    02815         Function == FSCTL_GET_OBJECT_ID ) {
    02816         irpSp->Parameters.FileSystemControl.OutputBufferLength = Length;
    02817     } else {
    02818         irpSp->Parameters.FileSystemControl.InputBufferLength = Length;
    02819     }
    02820
    02821     //
    02822     // Take out another reference to the file object to guarantee that it does
    02823     // not get deleted.
    02824     //
    02825
    02826     ObReferenceObject( FileObject );
    02827
    02828     //
    02829     // Call the driver to get the request.
    02830     //
    02831
    02832     status = IoCallDriver( deviceObject, irp );
    02833
    02834     //
    02835     // Synchronize completion of the request.
    02836     //
    02837
    02838     if (status == STATUS_PENDING) {
    02839         status = KeWaitForSingleObject( &event,
    02840                                         Executive,
    02841                                         KernelMode,
    02842                                         FALSE,
    02843                                         (PLARGE_INTEGER) NULL );
    02844         status = ioStatus.Status;
    02845     }
    02846
    02847     return status;
    02848 }

NTSTATUS IopGetSetSecurityObject | ( | IN PVOID | Object,
|  | IN SECURITY_OPERATION_CODE | OperationCode,
|  | IN PSECURITY_INFORMATION | SecurityInformation,
|  | IN OUT PSECURITY_DESCRIPTOR | SecurityDescriptor,
|  | IN OUT PULONG | CapturedLength,
|  | IN OUT PSECURITY_DESCRIPTOR * | ObjectsSecurityDescriptor,
|  | IN POOL_TYPE | PoolType,
|  | IN PGENERIC_MAPPING | GenericMapping
| ) |

Definition at line 975 of file objsup.c.

References AssignSecurityDescriptor, DeleteSecurityDescriptor, _FILE_OBJECT::DeviceObject, _FILE_OBJECT::Event, ExAcquireResourceExclusive, ExAcquireResourceShared, EXCEPTION_EXECUTE_HANDLER, Executive, ExReleaseResource, FALSE, _FILE_OBJECT::FileName, _IO_STACK_LOCATION::FileObject, _FILE_OBJECT::FinalStatus, _FILE_OBJECT::Flags, _IRP::Flags, FO_ALERTABLE_IO, FO_DIRECT_DEVICE_OPEN, FO_STREAM_FILE, FO_SYNCHRONOUS_IO, IO_TYPE_DEVICE, IoAllocateIrp(), IoCallDriver, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAcquireFastLock, IopAcquireFileObjectLock(), IopAllocateIrpCleanup(), IopGetDevicePDO(), IopQueueThreadIrp, IopReleaseFileObjectLock, IopSecurityResource, IopSetDeviceSecurityDescriptors(), IopUpdateOtherOperationCount(), IRP_MJ_QUERY_SECURITY, IRP_MJ_SET_SECURITY, IRP_SYNCHRONOUS_API, KeClearEvent, KeEnterCriticalRegion, KeInitializeEvent, KeLeaveCriticalRegion, KernelMode, KeWaitForSingleObject(), KPROCESSOR_MODE, _IO_STACK_LOCATION::MajorFunction, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, _IRP::Overlay, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PsGetCurrentThread, QuerySecurityDescriptor, _FILE_OBJECT::RelatedFileObject, _IRP::RequestorMode, SeAssignWorldSecurityDescriptor(), _DEVICE_OBJECT::SecurityDescriptor, SeQuerySecurityDescriptorInfo(), SetSecurityDescriptor, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserBuffer, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IopCreateObjectTypes().

    00988                    :
    00989
    00990     This routine is invoked to either query or set the security descriptor
    00991     for a file, directory, volume, or device.  It implements these functions
    00992     by either performing an in-line check if the file is a device or a
    00993     volume, or an I/O Request Packet (IRP) is generated and given to the
    00994     driver to perform the operation.
    00995
    00996 Arguments:
    00997
    00998     Object - Pointer to the file or device object representing the open object.
    00999
    01000     SecurityInformation - Information about what is being done to or obtained
    01001         from the object's security descriptor.
    01002
    01003     SecurityDescriptor - Supplies the base security descriptor and returns
    01004         the final security descriptor.  Note that if this buffer is coming
    01005         from user space, it has already been probed by the object manager
    01006         to length "CapturedLength", otherwise it points to kernel space and
    01007         should not be probed.  It must, however, be referenced in a try
    01008         clause.
    01009
    01010     CapturedLength - For a query operation this specifies the size, in
    01011         bytes, of the output security descriptor buffer and on return
    01012         contains the number of bytes needed to store the complete security
    01013         descriptor.  If the length needed is greater than the length
    01014         supplied the operation will fail.  This parameter is ignored for
    01015         the set and delete operations.  It is expected to point into
    01016         system space, ie, it need not be probed and it will not change.
    01017
    01018     ObjectsSecurityDescriptor - Supplies and returns the object's security
    01019         descriptor.
    01020
    01021     PoolType - Specifies from which type of pool memory is to be allocated.
    01022
    01023     GenericMapping - Supplies the generic mapping for the object type.
    01024
    01025 Return Value:
    01026
    01027     The final status of the operation is returned as the function value.
    01028
    01029 --*/
    01030
    01031 {
    01032     NTSTATUS status;
    01033     PFILE_OBJECT fileObject;
    01034     PDEVICE_OBJECT deviceObject;
    01035     PDEVICE_OBJECT devicePDO = NULL;
    01036     BOOLEAN synchronousIo;
    01037
    01038     UNREFERENCED_PARAMETER( ObjectsSecurityDescriptor );
    01039     UNREFERENCED_PARAMETER( PoolType );
    01040
    01041     PAGED_CODE();
    01042
    01043
    01044     //
    01045     // Begin by determining whether the security operation is to be performed
    01046     // in this routine or by the driver.  This is based upon whether the
    01047     // object represents a device object, or it represents a file object
    01048     // to a device, or a file on the device. If the open is a direct device
    01049     // open then use the device object.
    01050     //
    01051
    01052     if (((PDEVICE_OBJECT) (Object))->Type == IO_TYPE_DEVICE) {
    01053         deviceObject = (PDEVICE_OBJECT) Object;
    01054         fileObject = (PFILE_OBJECT) NULL;
    01055     } else {
    01056         fileObject = (PFILE_OBJECT) Object;
    01057         if (fileObject->Flags & FO_DIRECT_DEVICE_OPEN) {
    01058             deviceObject = IoGetAttachedDevice( fileObject->DeviceObject );
    01059         }
    01060         else {
    01061                 deviceObject = fileObject->DeviceObject;
    01062         }
    01063     }
    01064
    01065     if (!fileObject ||
    01066         (!fileObject->FileName.Length && !fileObject->RelatedFileObject) ||
    01067         (fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    01068
    01069         //
    01070         // This security operation is for the device itself, either through
    01071         // a file object, or directly to the device object.  For the latter
    01072         // case, assignment operations are also possible.  Also note that
    01073         // this may be a stream file object, which do not have security.
    01074         // The security for a stream file is actually represented by the
    01075         // security descriptor on the file itself, or the volume, or the
    01076         // device.
    01077         //
    01078
    01079         if (OperationCode == AssignSecurityDescriptor) {
    01080
    01081             //
    01082             // Simply assign the security descriptor to the device object,
    01083             // if this is a device object.
    01084             //
    01085
    01086             if (fileObject == NULL || !(fileObject->Flags & FO_STREAM_FILE)) {
    01087                 KeEnterCriticalRegion();
    01088                 ExAcquireResourceExclusive( &IopSecurityResource, TRUE );
    01089                 deviceObject->SecurityDescriptor = SecurityDescriptor;
    01090                 ExReleaseResource( &IopSecurityResource );
    01091                 KeLeaveCriticalRegion();
    01092             }
    01093             status = STATUS_SUCCESS;
    01094
    01095         } else if (OperationCode == SetSecurityDescriptor) {
    01096
    01097             //
    01098             // This is a set operation.  The SecurityInformation parameter
    01099             // determines what part of the SecurityDescriptor is going to
    01100             // be applied to the ObjectsSecurityDescriptor.
    01101             //
    01102
    01103             //
    01104             // if this deviceObject is attached to a PDO then we want
    01105             // to modify the security on the PDO and apply it up the
    01106             // device chain
    01107             //
    01108             if (fileObject == NULL || !(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    01109                 //
    01110                 // see if there is a PDO for this object, and obtain it
    01111                 //
    01112                 devicePDO = IopGetDevicePDO(deviceObject);
    01113             } else {
    01114                 devicePDO = NULL;
    01115             }
    01116             if (devicePDO) {
    01117                 //
    01118                 // set PDO and all attached device objects
    01119                 //
    01120                 status = IopSetDeviceSecurityDescriptors(devicePDO,SecurityInformation,SecurityDescriptor,PoolType,GenericMapping,TRUE);
    01121                 ObDereferenceObject( devicePDO );
    01122             } else {
    01123                 //
    01124                 // set this device object only
    01125                 //
    01126                 status = IopSetDeviceSecurityDescriptors(deviceObject,SecurityInformation,SecurityDescriptor,PoolType,GenericMapping,FALSE);
    01127             }
    01128
    01129         } else if (OperationCode == QuerySecurityDescriptor) {
    01130
    01131             //
    01132             // This is a get operation.  The SecurityInformation parameter
    01133             // determines what part of the SecurityDescriptor is going to
    01134             // be returned from the ObjectsSecurityDescriptor.
    01135             //
    01136
    01137             KeEnterCriticalRegion();
    01138             ExAcquireResourceShared( &IopSecurityResource, TRUE );
    01139             status = SeQuerySecurityDescriptorInfo( SecurityInformation,
    01140                                                     SecurityDescriptor,
    01141                                                     CapturedLength,
    01142                                                     &deviceObject->SecurityDescriptor );
    01143             ExReleaseResource( &IopSecurityResource );
    01144             KeLeaveCriticalRegion();
    01145
    01146         } else {
    01147
    01148             //
    01149             // This is a delete operation.  Simply indicate that everything
    01150             // worked just fine.
    01151             //
    01152
    01153             status = STATUS_SUCCESS;
    01154
    01155         }
    01156
    01157     } else if (OperationCode == DeleteSecurityDescriptor) {
    01158
    01159         //
    01160         // This is a delete operation for the security descriptor on a file
    01161         // object.  This function will be performed by the file system once
    01162         // the FCB itself is deleted.  Simply indicate that the operation
    01163         // was successful.
    01164         //
    01165
    01166         status = STATUS_SUCCESS;
    01167
    01168     } else {
    01169
    01170         PIRP irp;
    01171         IO_STATUS_BLOCK localIoStatus;
    01172         KEVENT event;
    01173         PIO_STACK_LOCATION irpSp;
    01174         KPROCESSOR_MODE requestorMode;
    01175
    01176         //
    01177         // This file object does not refer to the device itself.  Rather, it
    01178         // refers to either a file or a directory on the device.  This means
    01179         // that the request must be passed to the file system for processing.
    01180         // Note that the only requests that are passed through in this manner
    01181         // are SET or QUERY security operations.  DELETE operations have
    01182         // already been taken care of above since the file system which just
    01183         // drop the storage on the floor when it really needs to, and ASSIGN
    01184         // operations are irrelevant to file systems since they never
    01185         // generate one because they never assign the security descriptor
    01186         // to the object in the first place, they just assign it to the FCB.
    01187         //
    01188
    01189         requestorMode = KeGetPreviousMode();
    01190
    01191         //
    01192         // Begin by referencing the object by pointer.   Note that the object
    01193         // handle has already been checked for the appropriate access by the
    01194         // object system caller.  This reference must be performed because
    01195         // standard I/O completion will dereference the object.
    01196         //
    01197
    01198         ObReferenceObject( fileObject );
    01199
    01200         //
    01201         // Make a special check here to determine whether this is a synchronous
    01202         // I/O operation.  If it is, then wait here until the file is owned by
    01203         // the current thread.  If this is not a (serialized) synchronous I/O
    01204         // operation, then initialize the local event.
    01205         //
    01206
    01207         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    01208
    01209             BOOLEAN interrupted;
    01210
    01211             if (!IopAcquireFastLock( fileObject )) {
    01212                 status = IopAcquireFileObjectLock( fileObject,
    01213                                                    requestorMode,
    01214                                                    (BOOLEAN) ((fileObject->Flags & FO_ALERTABLE_IO) != 0),
    01215                                                    &interrupted );
    01216                 if (interrupted) {
    01217                     ObDereferenceObject( fileObject );
    01218                     return status;
    01219                 }
    01220             }
    01221             synchronousIo = TRUE;
    01222         } else {
    01223             KeInitializeEvent( &event, SynchronizationEvent, FALSE );
    01224             synchronousIo = FALSE;
    01225         }
    01226
    01227         //
    01228         // Set the file object to the Not-Signaled state.
    01229         //
    01230
    01231         KeClearEvent( &fileObject->Event );
    01232
    01233         //
    01234         // Get the address of the target device object.
    01235         //
    01236
    01237         deviceObject = IoGetRelatedDeviceObject( fileObject );
    01238
    01239         //
    01240         // Allocate and initialize the I/O Request Packet (IRP) for this
    01241         // operation.  The allocation is performed with an exception handler
    01242         // in case the caller does not have enough quota to allocate the packet.
    01243
    01244         irp = IoAllocateIrp( deviceObject->StackSize, TRUE );
    01245         if (!irp) {
    01246
    01247             //
    01248             // An IRP could not be allocated.  Cleanup and return an
    01249             // appropriate error status code.
    01250             //
    01251
    01252             IopAllocateIrpCleanup( fileObject, (PKEVENT) NULL );
    01253
    01254             return STATUS_INSUFFICIENT_RESOURCES;
    01255         }
    01256         irp->Tail.Overlay.OriginalFileObject = fileObject;
    01257         irp->Tail.Overlay.Thread = PsGetCurrentThread();
    01258         irp->RequestorMode = requestorMode;
    01259
    01260         //
    01261         // Fill in the service independent parameters in the IRP.
    01262         //
    01263
    01264         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    01265             irp->UserEvent = (PKEVENT) NULL;
    01266         } else {
    01267             irp->UserEvent = &event;
    01268             irp->Flags = IRP_SYNCHRONOUS_API;
    01269         }
    01270         irp->UserIosb = &localIoStatus;
    01271         irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    01272
    01273         //
    01274         // Get a pointer to the stack location for the first driver.  This will
    01275         // be used to pass the original function codes and parameters.
    01276         //
    01277
    01278         irpSp = IoGetNextIrpStackLocation( irp );
    01279
    01280         //
    01281         // Now determine whether this is a set or a query operation.
    01282         //
    01283
    01284         if (OperationCode == QuerySecurityDescriptor) {
    01285
    01286             //
    01287             // This is a query operation.  Fill in the appropriate fields in
    01288             // the stack location for the packet, as well as the fixed part
    01289             // of the packet.  Note that each of these parameters has been
    01290             // captured as well, so there is no need to perform any probing.
    01291             // The only exception is the UserBuffer memory may change, but
    01292             // that is the file system's responsibility to check.  Note that
    01293             // it has already been probed, so the pointer is at least not
    01294             // in an address space that the caller should not be accessing
    01295             // because of mode.
    01296             //
    01297
    01298             irpSp->MajorFunction = IRP_MJ_QUERY_SECURITY;
    01299             irpSp->Parameters.QuerySecurity.SecurityInformation = *SecurityInformation;
    01300             irpSp->Parameters.QuerySecurity.Length = *CapturedLength;
    01301             irp->UserBuffer = SecurityDescriptor;
    01302
    01303         } else {
    01304
    01305             //
    01306             // This is a set operation.  Fill in the appropriate fields in
    01307             // the stack location for the packet.  Note that access to the
    01308             // SecurityInformation parameter is safe, as the parameter was
    01309             // captured by the caller.  Likewise, the SecurityDescriptor
    01310             // refers to a captured copy of the descriptor.
    01311             //
    01312
    01313             irpSp->MajorFunction = IRP_MJ_SET_SECURITY;
    01314             irpSp->Parameters.SetSecurity.SecurityInformation = *SecurityInformation;
    01315             irpSp->Parameters.SetSecurity.SecurityDescriptor = SecurityDescriptor;
    01316
    01317         }
    01318
    01319         irpSp->FileObject = fileObject;
    01320
    01321         //
    01322         // Insert the packet at the head of the IRP list for the thread.
    01323         //
    01324
    01325         IopQueueThreadIrp( irp );
    01326
    01327         //
    01328         // Update the operation count statistic for the current process for
    01329         // operations other than read and write.
    01330         //
    01331
    01332         IopUpdateOtherOperationCount();
    01333
    01334         //
    01335         // Everything has been properly set up, so simply invoke the driver.
    01336         //
    01337
    01338         status = IoCallDriver( deviceObject, irp );
    01339
    01340         //
    01341         // If this operation was a synchronous I/O operation, check the return
    01342         // status to determine whether or not to wait on the file object.  If
    01343         // the file object is to be waited on, wait for the operation to be
    01344         // completed and obtain the final status from the file object itself.
    01345         //
    01346
    01347         if (synchronousIo) {
    01348             if (status == STATUS_PENDING) {
    01349                 (VOID) KeWaitForSingleObject( &fileObject->Event,
    01350                                               Executive,
    01351                                               KernelMode,
    01352                                               FALSE,
    01353                                               (PLARGE_INTEGER) NULL );
    01354                 status = fileObject->FinalStatus;
    01355             }
    01356             IopReleaseFileObjectLock( fileObject );
    01357
    01358         } else {
    01359
    01360             //
    01361             // This is a normal synchronous I/O operation, as opposed to a
    01362             // serialized synchronous I/O operation.  For this case, wait
    01363             // for the local event and return the final status information
    01364             // back to the caller.
    01365             //
    01366
    01367             if (status == STATUS_PENDING) {
    01368                 (VOID) KeWaitForSingleObject( &event,
    01369                                               Executive,
    01370                                               KernelMode,
    01371                                               FALSE,
    01372                                               (PLARGE_INTEGER) NULL );
    01373                 status = localIoStatus.Status;
    01374             }
    01375         }
    01376
    01377         //
    01378         // If this operation was just attempted on a file system or a device
    01379         // driver of some kind that does not implement security, then return
    01380         // a normal null security descriptor.
    01381         //
    01382
    01383         if (status == STATUS_INVALID_DEVICE_REQUEST) {
    01384
    01385             //
    01386             // The file system does not implement a security policy.  Determine
    01387             // what type of operation this was and implement the correct
    01388             // semantics for the file system.
    01389             //
    01390
    01391             if (OperationCode == QuerySecurityDescriptor) {
    01392
    01393                 //
    01394                 // The operation is a query.  If the caller's buffer is too
    01395                 // small, then indicate that this is the case and let him know
    01396                 // what size buffer is required.  Otherwise, attempt to return
    01397                 // a null security descriptor.
    01398                 //
    01399
    01400                try {
    01401                     status = SeAssignWorldSecurityDescriptor(
    01402                                  SecurityDescriptor,
    01403                                  CapturedLength,
    01404                                  SecurityInformation
    01405                                  );
    01406
    01407                 } except( EXCEPTION_EXECUTE_HANDLER ) {
    01408
    01409                     //
    01410                     // An exception was incurred while attempting to
    01411                     // access the caller's buffer.  Clean everything
    01412                     // up and return an appropriate status code.
    01413                     //
    01414
    01415                     status = GetExceptionCode();
    01416                 }
    01417
    01418             } else {
    01419
    01420                 //
    01421                 // This was an operation other than a query.  Simply indicate
    01422                 // that the operation was successful.
    01423                 //
    01424
    01425                 status = STATUS_SUCCESS;
    01426             }
    01427
    01428         } else if (OperationCode == QuerySecurityDescriptor) {
    01429
    01430             //
    01431             // The final return status from the file system was something
    01432             // other than invalid device request.  This means that the file
    01433             // system actually implemented the query.  Copy the size of the
    01434             // returned data, or the size of the buffer required in order
    01435             // to query the security descriptor.  Note that once again the
    01436             // assignment is performed inside of an exception handler in case
    01437             // the caller's buffer is inaccessible.  Also note that in order
    01438             // for the Information field of the I/O status block to be set,
    01439             // the file system must return a warning status.  Return the
    01440             // status that the caller expects if the buffer really is too
    01441             // small.
    01442             //
    01443
    01444             if (status == STATUS_BUFFER_OVERFLOW) {
    01445                 status = STATUS_BUFFER_TOO_SMALL;
    01446             }
    01447
    01448             try {
    01449
    01450                 *CapturedLength = (ULONG) localIoStatus.Information;
    01451
    01452             } except( EXCEPTION_EXECUTE_HANDLER ) {
    01453                 status = GetExceptionCode();
    01454             }
    01455         }
    01456     }
    01457
    01458     return status;
    01459 }
    }

NTSTATUS IopGetVolumeId | ( | IN PFILE_OBJECT | FileObject,
|  | IN OUT PLINK_TRACKING_INFORMATION | ObjectId,
|  | IN ULONG | Length
| ) |

| Referenced by IopTrackLink().

VOID IopHardErrorThread | ( | PVOID | StartContext | ) |

VOID IopInitializeResourceMap | ( | PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 66 of file report.c.

References _PHYSICAL_MEMORY_RUN::BasePage, CmRegistryMachineHardwareResourceMapName, ExAllocatePool, ExFreePool(), FALSE, IopOpenRegistryKey(), IopWriteResourceList(), IopWstrPhysicalMemory, IopWstrSpecialMemory, IopWstrSystem, IopWstrTranslated, LoaderMaximum, LoaderSpecialMemory, MAX_PHYSICAL_MEMORY_FRAGMENTS, MmInitializeMemoryLimits(), MmPhysicalMemoryBlock, NT_SUCCESS, NTSTATUS(), NULL, _PHYSICAL_MEMORY_DESCRIPTOR::NumberOfRuns, PAGE_SHIFT, _PHYSICAL_MEMORY_RUN::PageCount, PagedPool, RtlInitUnicodeString(), _PHYSICAL_MEMORY_DESCRIPTOR::Run, and TRUE.

Referenced by IoInitSystem().

    00075 {
    00076     ULONG i, j, pass, length;
    00077     LARGE_INTEGER li;
    00078     HANDLE keyHandle;
    00079     UNICODE_STRING  unicodeString, systemString, listString;
    00080     NTSTATUS status;
    00081     PCM_RESOURCE_LIST ResourceList;
    00082     PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor;
    00083     BOOLEAN IncludeType[LoaderMaximum];
    00084     ULONG MemoryAlloc[(sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
    00085             sizeof(PHYSICAL_MEMORY_RUN)*MAX_PHYSICAL_MEMORY_FRAGMENTS) /
    00086               sizeof(ULONG)];
    00087     PPHYSICAL_MEMORY_DESCRIPTOR MemoryBlock;
    00088
    00089     RtlInitUnicodeString( &systemString,  IopWstrSystem);
    00090     RtlInitUnicodeString( &listString, IopWstrTranslated );
    00091
    00092     for (pass=0; pass < 2; pass++) {
    00093         switch (pass) {
    00094             case 0:
    00095                 //
    00096                 // Add MmPhysicalMemoryBlock to regitry
    00097                 //
    00098
    00099                 RtlInitUnicodeString( &unicodeString, IopWstrPhysicalMemory);
    00100                 MemoryBlock = MmPhysicalMemoryBlock;
    00101                 break;
    00102
    00103             case 1:
    00104
    00105                 //
    00106                 // Add LoadSpecialMemory to registry
    00107                 //
    00108
    00109                 RtlInitUnicodeString( &unicodeString, IopWstrSpecialMemory);
    00110
    00111                 //
    00112                 // Computer memory limits of LoaderSpecialMemory
    00113                 //
    00114
    00115                 MemoryBlock = (PPHYSICAL_MEMORY_DESCRIPTOR)&MemoryAlloc;
    00116                 MemoryBlock->NumberOfRuns = MAX_PHYSICAL_MEMORY_FRAGMENTS;
    00117
    00118                 for (j=0; j < LoaderMaximum; j++) {
    00119                     IncludeType[j] = FALSE;
    00120                 }
    00121                 IncludeType[LoaderSpecialMemory] = TRUE;
    00122                 MmInitializeMemoryLimits(
    00123                     LoaderBlock,
    00124                     IncludeType,
    00125                     MemoryBlock
    00126                     );
    00127
    00128                 break;
    00129         }
    00130
    00131         //
    00132         // Allocate and build a CM_RESOURCE_LIST to describe all
    00133         // of physical memory
    00134         //
    00135
    00136         j = MemoryBlock->NumberOfRuns;
    00137         if (j == 0) {
    00138             continue;
    00139         }
    00140
    00141         length = sizeof(CM_RESOURCE_LIST) + (j-1) * sizeof (CM_PARTIAL_RESOURCE_DESCRIPTOR);
    00142         ResourceList = (PCM_RESOURCE_LIST) ExAllocatePool (PagedPool, length);
    00143         if (!ResourceList) {
    00144             return;
    00145         }
    00146         RtlZeroMemory ((PVOID) ResourceList, length);
    00147
    00148         ResourceList->Count = 1;
    00149         ResourceList->List[0].PartialResourceList.Count = j;
    00150         CmDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
    00151
    00152         for (i=0; i < j; i++) {
    00153             CmDescriptor->Type = CmResourceTypeMemory;
    00154             CmDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
    00155             li.QuadPart = (LONGLONG)(MemoryBlock->Run[i].BasePage);
    00156             li.QuadPart <<= PAGE_SHIFT;
    00157             CmDescriptor->u.Memory.Start  = li;
    00158
    00159             // fixfix - handle page frame numbers greater than 32 bits.
    00160
    00161             CmDescriptor->u.Memory.Length =
    00162                 (ULONG)(MemoryBlock->Run[i].PageCount << PAGE_SHIFT);
    00163
    00164             CmDescriptor++;
    00165         }
    00166
    00167
    00168         //
    00169         // Add the resoruce list to the resorucemap
    00170         //
    00171
    00172         status = IopOpenRegistryKey( &keyHandle,
    00173                                      (HANDLE) NULL,
    00174                                      &CmRegistryMachineHardwareResourceMapName,
    00175                                      KEY_READ | KEY_WRITE,
    00176                                      TRUE );
    00177         if (NT_SUCCESS( status )) {
    00178             IopWriteResourceList ( keyHandle,
    00179                                    &systemString,
    00180                                    &unicodeString,
    00181                                    &listString,
    00182                                    ResourceList,
    00183                                    length
    00184                                    );
    00185             ZwClose( keyHandle );
    00186         }
    00187         ExFreePool (ResourceList);
    00188     }
    00189 }

VOID IopInsertRemoveDevice | ( | IN PDRIVER_OBJECT | DriverObject,
|  | IN PDEVICE_OBJECT | DeviceObject,
|  | IN BOOLEAN | Insert
| ) |

Definition at line 4026 of file iosubs.c.

References _DRIVER_OBJECT::DeviceObject, _DEVICE_OBJECT::DriverObject, IopDatabaseLock, and _DEVICE_OBJECT::NextDevice.

Referenced by IoCreateDevice(), and IopCompleteUnloadOrDelete().

    04032 {
    04033     KIRQL irql;
    04034
    04035     ExAcquireSpinLock( &IopDatabaseLock, &irql );
    04036     if (Insert) {
    04037         DeviceObject->NextDevice = DriverObject->DeviceObject;
    04038         DriverObject->DeviceObject = DeviceObject;
    04039         }
    04040     else {
    04041         PDEVICE_OBJECT *prevPoint;
    04042
    04043         prevPoint = &DeviceObject->DriverObject->DeviceObject;
    04044         while (*prevPoint != DeviceObject) {
    04045             prevPoint = &(*prevPoint)->NextDevice;
    04046         }
    04047         *prevPoint = DeviceObject->NextDevice;
    04048     }
    04049     ExReleaseSpinLock( &IopDatabaseLock, irql );
    04050 }

NTSTATUS IopInvalidateVolumesForDevice | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 4710 of file internal.c.

References _DEVICE_OBJECT::AttachedDevice, ExAcquireResourceShared, EXCEPTION_EXECUTE_HANDLER, Executive, ExReleaseResource, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, IoCreateStreamFileObjectLite(), IoFileObjectType, IoGetNextIrpStackLocation, IopCdRomFileSystemQueueHead, IopDatabaseResource, IopDiskFileSystemQueueHead, IopTapeFileSystemQueueHead, IRP_MJ_FILE_SYSTEM_CONTROL, KeClearEvent, KeEnterCriticalRegion, KeInitializeEvent, KeLeaveCriticalRegion, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObOpenObjectByPointer(), PAGED_CODE, TRUE, VOID(), _DEVICE_OBJECT::Vpb, and _FILE_OBJECT::Vpb.

Referenced by IopRemoveDevice().

    04716                    :
    04717
    04718     This routine is used to force filesystems to, as completely as possible, throw
    04719     out volumes which remain referenced for a given device.
    04720
    04721 Arguments:
    04722
    04723     DeviceObject - Pointer to device object for which volumes are to be
    04724         invalidated.
    04725
    04726 Return Value:
    04727
    04728     The function value is a successful status code if all filesystems accepted the
    04729     operation.  Otherwise, an error code is returned.
    04730
    04731 --*/
    04732
    04733 {
    04734     NTSTATUS status;
    04735     NTSTATUS finalStatus;
    04736     KEVENT event;
    04737     PIRP irp;
    04738     PDEVICE_OBJECT fsDeviceObject;
    04739     PDEVICE_OBJECT attachedDevice;
    04740     PFILE_OBJECT storageFileObject;
    04741     HANDLE storageHandle;
    04742     PLIST_ENTRY entry;
    04743     PLIST_ENTRY queueHeader;
    04744     IO_STATUS_BLOCK ioStatus;
    04745     PIO_STACK_LOCATION irpSp;
    04746
    04747     PAGED_CODE();
    04748
    04749     //
    04750     // Now acquire the resource database lock for the I/O system to perform this
    04751     // operation.  This resource protects access to the file system queue.
    04752     //
    04753
    04754     KeEnterCriticalRegion();
    04755     (VOID) ExAcquireResourceShared( &IopDatabaseResource, TRUE );
    04756
    04757     //
    04758     // Get the actual device that would be mounted on.  This device is the final
    04759     // device in the list of devices which are attached to the specified real device.
    04760     //
    04761
    04762     attachedDevice = DeviceObject;
    04763     while (attachedDevice->AttachedDevice) {
    04764         attachedDevice = attachedDevice->AttachedDevice;
    04765     }
    04766
    04767     //
    04768     // Get a handle to this device for use in the fsctl.  The way we have to do
    04769     // this is kind of loopy: note we wind up with two references to clean up.
    04770     //
    04771     // The only use of this fileobject/handle is to communicate the device to
    04772     // invalidate volumes on.  It isn't used for anything else, and must not be.
    04773     //
    04774
    04775     try {
    04776
    04777         storageFileObject = NULL;
    04778         storageFileObject = IoCreateStreamFileObjectLite( NULL, attachedDevice );
    04779         storageFileObject->Vpb = attachedDevice->Vpb;
    04780
    04781         storageHandle = NULL;
    04782         status = ObOpenObjectByPointer( storageFileObject,
    04783                                         OBJ_KERNEL_HANDLE,
    04784                                         NULL,
    04785                                         0,
    04786                                         IoFileObjectType,
    04787                                         KernelMode,
    04788                                         &storageHandle );
    04789
    04790     } except(EXCEPTION_EXECUTE_HANDLER) {
    04791
    04792         status = GetExceptionCode();
    04793     }
    04794
    04795     if (NT_SUCCESS( status )) {
    04796
    04797         //
    04798         // Determine which type of file system should be invoked based on
    04799         // the device type of the device being invalidated.
    04800         //
    04801
    04802         if (DeviceObject->DeviceType == FILE_DEVICE_DISK ||
    04803             DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK) {
    04804             queueHeader = &IopDiskFileSystemQueueHead;
    04805         } else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM) {
    04806             queueHeader = &IopCdRomFileSystemQueueHead;
    04807         } else {
    04808             queueHeader = &IopTapeFileSystemQueueHead;
    04809         }
    04810
    04811         //
    04812         // Initialize the event and set the status to set up
    04813         // for the loop.
    04814         //
    04815
    04816         KeInitializeEvent( &event, NotificationEvent, FALSE );
    04817         finalStatus = STATUS_SUCCESS;
    04818
    04819         //
    04820         // Now loop through each of the file systems which have been loaded in
    04821         // the system and ask them to invalidate volumes they have had mounted
    04822         // on it.
    04823         //
    04824
    04825         for (entry = queueHeader->Flink;
    04826              entry != queueHeader;
    04827              entry = entry->Flink) {
    04828
    04829             //
    04830             // If this is the final entry (Raw file system), then break out of the
    04831             // loop at this point, as volumes cannot be invalidated for the caller's
    04832             // purposes in Raw.
    04833             //
    04834
    04835             if (entry->Flink == queueHeader) {
    04836                 break;
    04837             }
    04838
    04839             fsDeviceObject = CONTAINING_RECORD( entry, DEVICE_OBJECT, Queue.ListEntry );
    04840
    04841             //
    04842             // It is possible that the file system has been attached to, so
    04843             // walk the attached list for the file system.
    04844             //
    04845
    04846             while (fsDeviceObject->AttachedDevice) {
    04847                 fsDeviceObject = fsDeviceObject->AttachedDevice;
    04848             }
    04849
    04850             //
    04851             // Another file system has been found.  Attempt to invalidate volumes
    04852             // using this file system.
    04853             //
    04854             // Begin by resetting the event being used for synchronization with
    04855             // the I/O operation.
    04856             //
    04857
    04858             KeClearEvent( &event );
    04859
    04860             //
    04861             // Build an IRP for this operation.
    04862             //
    04863
    04864             irp = IoBuildDeviceIoControlRequest( FSCTL_INVALIDATE_VOLUMES,
    04865                                                  fsDeviceObject,
    04866                                                  &storageHandle,
    04867                                                  sizeof(HANDLE),
    04868                                                  NULL,
    04869                                                  0,
    04870                                                  FALSE,
    04871                                                  &event,
    04872                                                  &ioStatus );
    04873
    04874             if (irp == NULL) {
    04875
    04876                 finalStatus = STATUS_INSUFFICIENT_RESOURCES;
    04877                 break;
    04878             }
    04879
    04880             irpSp = IoGetNextIrpStackLocation( irp );
    04881             irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
    04882
    04883             status = IoCallDriver( fsDeviceObject, irp );
    04884
    04885             //
    04886             // Wait for the I/O operation to complete.
    04887             //
    04888
    04889             if (status == STATUS_PENDING) {
    04890                 (VOID) KeWaitForSingleObject( &event,
    04891                                               Executive,
    04892                                               KernelMode,
    04893                                               FALSE,
    04894                                               (PLARGE_INTEGER) NULL );
    04895
    04896                 status = ioStatus.Status;
    04897
    04898             } else {
    04899
    04900                 //
    04901                 // Ensure that the proper status value gets picked up.
    04902                 //
    04903
    04904                 ioStatus.Status = status;
    04905                 ioStatus.Information = 0;
    04906             }
    04907
    04908             //
    04909             // Commute status' indicating the operation is not implemented
    04910             // to success.  If a filesystem does not implement, it must not
    04911             // hold volumes that are not mounted.
    04912             //
    04913
    04914             if (status == STATUS_INVALID_DEVICE_REQUEST ||
    04915                 status == STATUS_NOT_IMPLEMENTED) {
    04916
    04917                 status = STATUS_SUCCESS;
    04918             }
    04919
    04920             //
    04921             //  Hand back the first failure we get, but plow on anyway.
    04922             //
    04923
    04924             if (NT_SUCCESS( finalStatus ) && !NT_SUCCESS( status )) {
    04925                 finalStatus = status;
    04926             }
    04927         }
    04928
    04929         if (storageFileObject) {
    04930             ObDereferenceObject( storageFileObject );
    04931             if (storageHandle) {
    04932                 ZwClose( storageHandle );
    04933             }
    04934         }
    04935
    04936         status = finalStatus;
    04937     }
    04938
    04939     ExReleaseResource( &IopDatabaseResource );
    04940     KeLeaveCriticalRegion();
    04941
    04942     return status;
    04943 }

NTSTATUS IopInvalidDeviceRequest | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PIRP | Irp
| ) |

Definition at line 3087 of file internal.c.

References IO_NO_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_MJ_POWER, and PoStartNextPowerIrp().

Referenced by IoCreateDriver(), IopLoadDriver(), and IovpAssertIrpStackDownward().

    03094                    :
    03095
    03096     This function is the default dispatch routine for all driver entries
    03097     not implemented by drivers that have been loaded into the system.  Its
    03098     responsibility is simply to set the status in the packet to indicate
    03099     that the operation requested is invalid for this device type, and then
    03100     complete the packet.
    03101
    03102 Arguments:
    03103
    03104     DeviceObject - Specifies the device object for which this request is
    03105         bound.  Ignored by this routine.
    03106
    03107     Irp - Specifies the address of the I/O Request Packet (IRP) for this
    03108         request.
    03109
    03110 Return Value:
    03111
    03112     The final status is always STATUS_INVALID_DEVICE_REQUEST.
    03113
    03114
    03115 --*/
    03116
    03117 {
    03118     UNREFERENCED_PARAMETER( DeviceObject );
    03119
    03120     //
    03121     // Simply store the appropriate status, complete the request, and return
    03122     // the same status stored in the packet.
    03123     //
    03124
    03125     if ((IoGetCurrentIrpStackLocation(Irp))->MajorFunction == IRP_MJ_POWER) {
    03126         PoStartNextPowerIrp(Irp);
    03127     }
    03128     Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
    03129     IoCompleteRequest( Irp, IO_NO_INCREMENT );
    03130     return STATUS_INVALID_DEVICE_REQUEST;
    03131 }

BOOLEAN IopIsRemoteBootCard | ( | IN PDEVICE_NODE | DeviceNode,
|  | IN PLOADER_PARAMETER_BLOCK | LoaderBlock,
|  | IN PWCHAR | HwIds
| ) |

Definition at line 1903 of file netboot.c.

References BusNumber, FALSE, L, _SETUP_LOADER_BLOCK::NetbootCardHardwareId, _SETUP_LOADER_BLOCK::NetbootCardInfo, PSETUP_LOADER_BLOCK, and TRUE.

Referenced by IopProcessNewDeviceNode().

    01911                    :
    01912
    01913     This function determines if the card described by the hwIds is the
    01914     remote boot network card. It checks against the hardware ID for the
    01915     card that is stored in the setup loader block.
    01916
    01917     THIS ASSUMES THAT IOREMOTEBOOTCLIENT IS TRUE AND THAT LOADERBLOCK
    01918     IS VALID.
    01919
    01920 Arguments:
    01921
    01922     DeviceNode - Device node for the card in question.
    01923
    01924     LoaderBlock - Supplies a pointer to the loader parameter block that was
    01925         created by the OS Loader.
    01926
    01927     HwIds - The hardware IDs for the device in question.
    01928
    01929 Return Value:
    01930
    01931     TRUE or FALSE.
    01932
    01933 --*/
    01934
    01935 {
    01936     PSETUP_LOADER_BLOCK setupLoaderBlock;
    01937     PWCHAR curHwId;
    01938
    01939     //
    01940     // setupLoaderBlock will always be non-NULL if we are
    01941     // remote booting, even if we are not in setup.
    01942     //
    01943
    01944     setupLoaderBlock = LoaderBlock->SetupLoaderBlock;
    01945
    01946     //
    01947     // Scan through the HwIds for a match.
    01948     //
    01949
    01950     curHwId = HwIds;
    01951
    01952     while (*curHwId != L'\0') {
    01953         if (wcscmp(curHwId, setupLoaderBlock->NetbootCardHardwareId) == 0) {
    01954
    01955             ULONG BusNumber, SlotNumber;
    01956
    01957             BusNumber = (ULONG)((((PNET_CARD_INFO)setupLoaderBlock->NetbootCardInfo)->pci.BusDevFunc) >> 8);
    01958             SlotNumber = (ULONG)(((((PNET_CARD_INFO)setupLoaderBlock->NetbootCardInfo)->pci.BusDevFunc) & 0xf8) >> 3);
    01959
    01960             KdPrint(("IopIsRemoteBootCard: FOUND %ws\n", setupLoaderBlock->NetbootCardHardwareId));
    01961             if ((DeviceNode->ResourceRequirements->BusNumber != BusNumber) ||
    01962                 (DeviceNode->ResourceRequirements->SlotNumber != SlotNumber)) {
    01963                 KdPrint(("IopIsRemoteBootCard: ignoring non-matching card:\n"));
    01964                 KdPrint(("  devnode bus %d, busdevfunc bus %d\n",
    01965                     DeviceNode->ResourceRequirements->BusNumber,
    01966                     BusNumber));
    01967                 KdPrint(("  devnode slot %d, busdevfunc slot %d\n",
    01968                     DeviceNode->ResourceRequirements->SlotNumber,
    01969                     SlotNumber));
    01970                 return FALSE;
    01971             } else {
    01972                 return TRUE;
    01973             }
    01974         }
    01975         curHwId += (wcslen(curHwId) + 1);
    01976     }
    01977
    01978     return FALSE;
    01979 }

BOOLEAN IopIsSameMachine | ( | IN PFILE_OBJECT | SourceFile,
|  | IN HANDLE | TargetFile
| ) |

Definition at line 3134 of file internal.c.

References _DEVICE_OBJECT::DriverObject, _FAST_IO_DISPATCH::FastIoDeviceControl, _DRIVER_OBJECT::FastIoDispatch, IoGetRelatedDeviceObject(), NTSTATUS(), NULL, PAGED_CODE, and TRUE.

Referenced by IopTrackLink().

    03141                    :
    03142
    03143     This routine is invoked to determine whether two file objects that represent
    03144     files on remote machines actually reside on the same physical system.
    03145
    03146 Arguments:
    03147
    03148     SourceFile - Supplies the file object for the first file.
    03149
    03150     TargetFile - Supplies the file object for the second file.
    03151
    03152 Return Value:
    03153
    03154     The final function value is TRUE if the files reside on the same machine,
    03155     otherwise FALSE is returned.
    03156
    03157 --*/
    03158
    03159 {
    03160     PDEVICE_OBJECT deviceObject;
    03161     PFAST_IO_DISPATCH fastIoDispatch;
    03162     NTSTATUS status = STATUS_NOT_SAME_DEVICE;
    03163     IO_STATUS_BLOCK ioStatus;
    03164     HANDLE target = TargetFile;
    03165
    03166     PAGED_CODE();
    03167
    03168     //
    03169     // Simply invoke the device I/O control function to determine whether or
    03170     // not the two files are on the same server.  If the fast I/O path does
    03171     // not exist, or the function fails for any reason, then the two files are
    03172     // assumed to not be on the same machine.  Note that this simply means
    03173     // that there will be a performance penalty on open of the target, but
    03174     // the above will only fail if the two files really aren't on the same
    03175     // machine in the first place, or if there's a filter that doesn't under-
    03176     // stand what is being done here.
    03177     //
    03178
    03179     deviceObject = IoGetRelatedDeviceObject( SourceFile );
    03180
    03181     fastIoDispatch = deviceObject->DriverObject->FastIoDispatch;
    03182     if (fastIoDispatch && fastIoDispatch->FastIoDeviceControl) {
    03183         if (fastIoDispatch->FastIoDeviceControl( SourceFile,
    03184                                                  TRUE,
    03185                                                  (PVOID) &target,
    03186                                                  sizeof( target ),
    03187                                                  (PVOID) NULL,
    03188                                                  0,
    03189                                                  IOCTL_LMR_ARE_FILE_OBJECTS_ON_SAME_SERVER,
    03190                                                  &ioStatus,
    03191                                                  deviceObject )) {
    03192             status = ioStatus.Status;
    03193         }
    03194     }
    03195
    03196     return status == STATUS_SUCCESS;
    03197 }

NTSTATUS IopLoadDriver | ( | IN HANDLE | KeyHandle,
|  | IN BOOLEAN | CheckForSafeBoot
| ) |

Definition at line 3200 of file internal.c.

References ASSERT, CmBootLastKnownGood(), CmRegistryMachineHardwareDescriptionSystemName, DbgPrint, DRIVER_EXTENSION, DRIVER_OBJECT, DRVO_LEGACY_DRIVER, DRVO_REINIT_REGISTERED, DRVO_UNLOAD_INVOKED, ExAcquireResourceShared, ExAllocatePool, ExFreePool(), ExReleaseResource, FALSE, InitSafeBootMode, IO_TYPE_DRIVER, IoDriverObjectType, IopBootLog(), IopDeleteLegacyKey(), IopDriverLoadingFailed(), IopGetDriverNameFromKeyNode(), IopGetRegistryValue(), IopInvalidDeviceRequest(), IopIsAnyDeviceInstanceEnabled(), IopIsLegacyDriver(), IopPrepareDriverLoading(), IopReadyDeviceObjects(), IopResurrectDriver(), IopSafebootDriverLoad(), IopStartDriverDevices(), IRP_MJ_MAXIMUM_FUNCTION, KeQuerySystemTime(), KernelMode, L, MmFreeDriverInitialization(), MmLoadSystemImage(), MmUnloadSystemImage(), NonPagedPool, NT_SUCCESS, NtClose(), NtQueryKey(), NtQueryObject(), NtQueryValueKey(), NTSTATUS(), NULL, ObCreateObject(), ObDereferenceObject, ObInsertObject(), ObMakeTemporaryObject(), ObOpenObjectByName(), ObReferenceObjectByHandle(), PAGE_SIZE, PAGED_CODE, PagedPool, PDRIVER_EXTENSION, PDRIVER_INITIALIZE, PERFINFO_DRIVER_INIT, PERFINFO_DRIVER_INIT_COMPLETE, PnPInitialized, PsLoadedModuleList, PsLoadedModuleResource, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlEqualString(), RtlImageNtHeader(), RtlInitUnicodeString(), TRUE, and USHORT.

Referenced by IopCallDriverAddDeviceQueryRoutine(), IopInitializeSystemDrivers(), and IopLoadUnloadDriver().

    03207                    :
    03208
    03209     This routine is invoked to load a device or file system driver, either
    03210     during system initialization, or dynamically while the system is running.
    03211
    03212 Arguments:
    03213
    03214     KeyHandle - Supplies a handle to the driver service node in the registry
    03215         that describes the driver to be loaded.
    03216
    03217 Return Value:
    03218
    03219     The function value is the final status of the load operation.
    03220
    03221 Notes:
    03222
    03223     Note that this routine closes the KeyHandle before returning.
    03224
    03225
    03226 --*/
    03227
    03228 {
    03229     NTSTATUS status;
    03230     PLIST_ENTRY nextEntry;
    03231     PLDR_DATA_TABLE_ENTRY driverEntry;
    03232     PKEY_BASIC_INFORMATION keyBasicInformation = NULL;
    03233     PKEY_VALUE_FULL_INFORMATION keyValueInformation = NULL;
    03234     ULONG keyBasicLength;
    03235     UNICODE_STRING baseName;
    03236     UNICODE_STRING serviceName = {0, 0, NULL};
    03237     OBJECT_ATTRIBUTES objectAttributes;
    03238     PVOID sectionPointer;
    03239     UNICODE_STRING driverName;
    03240     PDRIVER_OBJECT driverObject;
    03241     PIMAGE_NT_HEADERS ntHeaders;
    03242     PVOID imageBaseAddress;
    03243     ULONG_PTR entryPoint;
    03244     HANDLE driverHandle;
    03245     ULONG i;
    03246     POBJECT_NAME_INFORMATION registryPath;
    03247 #if DBG
    03248     LARGE_INTEGER stime, etime;
    03249     ULONG dtime;
    03250 #endif
    03251
    03252     PAGED_CODE();
    03253
    03254     driverName.Buffer = (PWSTR) NULL;
    03255
    03256     //
    03257     // Begin by formulating the name of the driver image file to be loaded.
    03258     // Note that this is used to determine whether or not the driver has
    03259     // already been loaded by the OS loader, not necessarily in actually
    03260     // loading the driver image, since the node can override that name.
    03261     //
    03262
    03263     status = NtQueryKey( KeyHandle,
    03264                          KeyBasicInformation,
    03265                          (PVOID) NULL,
    03266                          0,
    03267                          &keyBasicLength );
    03268     if (status != STATUS_BUFFER_OVERFLOW &&
    03269         status != STATUS_BUFFER_TOO_SMALL) {
    03270         status = STATUS_ILL_FORMED_SERVICE_ENTRY;
    03271         goto IopLoadExit;
    03272     }
    03273
    03274     keyBasicInformation = ExAllocatePool( NonPagedPool,
    03275                                           keyBasicLength + (4 * 2) );
    03276     if (!keyBasicInformation) {
    03277         status = STATUS_INSUFFICIENT_RESOURCES;
    03278         goto IopLoadExit;
    03279     }
    03280
    03281     status = NtQueryKey( KeyHandle,
    03282                          KeyBasicInformation,
    03283                          keyBasicInformation,
    03284                          keyBasicLength,
    03285                          &keyBasicLength );
    03286     if (!NT_SUCCESS( status )) {
    03287         goto IopLoadExit;
    03288     }
    03289
    03290     //
    03291     // Create a Unicode string descriptor which forms the name of the
    03292     // driver.
    03293     //
    03294
    03295     baseName.Length = (USHORT) keyBasicInformation->NameLength;
    03296     baseName.MaximumLength = (USHORT) (baseName.Length + (4 * 2));
    03297     baseName.Buffer = &keyBasicInformation->Name[0];
    03298 //#if _PNP_POWER_
    03299     serviceName.Buffer = ExAllocatePool(PagedPool, baseName.Length + sizeof(UNICODE_NULL));
    03300     if (serviceName.Buffer) {
    03301         serviceName.Length = baseName.Length;
    03302         serviceName.MaximumLength = serviceName.Length + sizeof(UNICODE_NULL);
    03303         RtlMoveMemory(serviceName.Buffer, baseName.Buffer, baseName.Length);
    03304         serviceName.Buffer[serviceName.Length / sizeof(WCHAR)] = UNICODE_NULL;
    03305     }
    03306 #if DBG
    03307       else {
    03308         DbgPrint("IopLoadDriver: No memory available for Service Keyname\n");
    03309     }
    03310 #endif
    03311 //#endif
    03312     RtlAppendUnicodeToString( &baseName, L".SYS" );
    03313
    03314     if (CheckForSafeBoot && InitSafeBootMode) {
    03315
    03316         BOOLEAN GroupIsGood = FALSE;
    03317         UNICODE_STRING string;
    03318         PKEY_VALUE_PARTIAL_INFORMATION keyValue;
    03319         UCHAR nameBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 64];
    03320         ULONG length;
    03321
    03322         RtlInitUnicodeString( &string, L"Group" );
    03323         keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)nameBuffer;
    03324         RtlZeroMemory(nameBuffer, sizeof(nameBuffer));
    03325
    03326         status = NtQueryValueKey(
    03327             KeyHandle,
    03328             &string,
    03329             KeyValuePartialInformation,
    03330             keyValue,
    03331             sizeof(nameBuffer),
    03332             &length
    03333             );
    03334         if (NT_SUCCESS(status)) {
    03335
    03336             string.Length = (USHORT)(keyValue->DataLength - sizeof(WCHAR));
    03337             string.MaximumLength = string.Length;
    03338             string.Buffer = (PWSTR)keyValue->Data;
    03339
    03340             if (IopSafebootDriverLoad(&string)) {
    03341                 GroupIsGood = TRUE;
    03342             }
    03343         }
    03344
    03345         if (!GroupIsGood && !IopSafebootDriverLoad(&baseName)) {
    03346             //
    03347             // don't load the driver
    03348             //
    03349
    03350             IopBootLog(&baseName, FALSE);
    03351
    03352             DbgPrint("SAFEBOOT: skipping device = %wZ(%wZ)\n",&baseName,&string);
    03353             return STATUS_SUCCESS;
    03354         }
    03355
    03356     }
    03357
    03358     //
    03359     // See if this driver has already been loaded by the boot loader.
    03360     //
    03361
    03362     //KeEnterCriticalRegion();
    03363     ExAcquireResourceShared( &PsLoadedModuleResource, TRUE );
    03364     nextEntry = PsLoadedModuleList.Flink;
    03365     while (nextEntry != &PsLoadedModuleList) {
    03366
    03367         //
    03368         // Look at the next boot driver in the list.
    03369         //
    03370
    03371         driverEntry = CONTAINING_RECORD( nextEntry,
    03372                                          LDR_DATA_TABLE_ENTRY,
    03373                                          InLoadOrderLinks );
    03374
    03375         //
    03376         // If this is not the kernel image (ntoskrnl) and not the HAL (hal),
    03377         // then this is a driver, so initialize it.
    03378         //
    03379
    03380         if ((driverEntry->Flags & LDRP_ENTRY_PROCESSED) &&
    03381             RtlEqualString( (PSTRING) &baseName,
    03382                             (PSTRING) &driverEntry->FullDllName,
    03383                             TRUE )) {
    03384             status = STATUS_IMAGE_ALREADY_LOADED;
    03385             ExReleaseResource( &PsLoadedModuleResource );
    03386             //KeLeaveCriticalRegion();
    03387
    03388             IopBootLog(&baseName, TRUE);
    03389
    03390             goto IopLoadExit;
    03391         }
    03392
    03393         nextEntry = nextEntry->Flink;
    03394     }
    03395     ExReleaseResource( &PsLoadedModuleResource );
    03396     //KeLeaveCriticalRegion();
    03397
    03398     //
    03399     // This driver has not already been loaded by the OS loader.  Form the
    03400     // full path name for this driver.  Begin by attempting to determine
    03401     // whether or not the file has an image path.  If so, then use that,
    03402     // otherwise, form one from the above driver name by putting the
    03403     // appropriate path name in front of it.
    03404     //
    03405
    03406     status = IopGetRegistryValue( KeyHandle,
    03407                                   L"ImagePath",
    03408                                   &keyValueInformation );
    03409
    03410     if (NT_SUCCESS( status ) && keyValueInformation->DataLength) {
    03411
    03412         //
    03413         // The driver service node contained an image path name from which
    03414         // the driver is to be loaded.
    03415         //
    03416
    03417         ExFreePool( keyBasicInformation );
    03418         keyBasicInformation = NULL;
    03419         baseName.Length = (USHORT) keyValueInformation->DataLength;
    03420         if (baseName.Length > 0) {
    03421             baseName.Length -= sizeof( WCHAR );
    03422         }
    03423         baseName.MaximumLength = baseName.Length;
    03424         baseName.Buffer = (PWSTR) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset);
    03425
    03426         if (baseName.Buffer[0] != L'\\') {
    03427
    03428             UNICODE_STRING prefixName;
    03429             UNICODE_STRING tmpName;
    03430             PWCHAR fileName;
    03431
    03432             RtlInitUnicodeString( &prefixName, L"\\SystemRoot\\" );
    03433             fileName = ExAllocatePool( NonPagedPool,
    03434                                        prefixName.Length + baseName.Length );
    03435             if (!fileName) {
    03436                 status = STATUS_INSUFFICIENT_RESOURCES;
    03437                 goto IopLoadExit;
    03438             }
    03439
    03440             tmpName.Length = baseName.Length;
    03441             tmpName.Buffer = baseName.Buffer;
    03442             baseName.MaximumLength = (USHORT) (prefixName.Length + baseName.Length);
    03443             baseName.Length = 0;
    03444             baseName.Buffer = fileName;
    03445
    03446             RtlAppendUnicodeStringToString( &baseName, &prefixName );
    03447             RtlAppendUnicodeStringToString( &baseName, &tmpName );
    03448
    03449             ExFreePool( keyValueInformation );
    03450             keyValueInformation = (PKEY_VALUE_FULL_INFORMATION) fileName;
    03451         }
    03452
    03453     } else {
    03454
    03455         UNICODE_STRING prefixName;
    03456         UNICODE_STRING fileName;
    03457
    03458         RtlInitUnicodeString( &prefixName, L"\\SystemRoot\\System32\\Drivers\\" );
    03459
    03460         //
    03461         // Ensure that the driver entry did not actually contain an image path
    03462         // name, and if it did, free the appropriate pool because it was a key
    03463         // without a value.
    03464         //
    03465
    03466         if (NT_SUCCESS( status )) {
    03467             ExFreePool( keyValueInformation );
    03468         }
    03469
    03470         //
    03471         // The driver entry did not contain an image path name, so the above
    03472         // default name for the driver image is name of the file.  Form a
    03473         // fully qualified path to get to the image file.
    03474         //
    03475
    03476         keyValueInformation = ExAllocatePool( NonPagedPool,
    03477                                               baseName.MaximumLength +
    03478                                               prefixName.Length );
    03479         if (!keyValueInformation) {
    03480             status = STATUS_INSUFFICIENT_RESOURCES;
    03481             goto IopLoadExit;
    03482         }
    03483
    03484         fileName.Length = baseName.Length;
    03485         fileName.MaximumLength = baseName.MaximumLength;
    03486         fileName.Buffer = baseName.Buffer;
    03487
    03488         baseName.Length = 0;
    03489         baseName.MaximumLength = (USHORT) (fileName.Length + prefixName.Length);
    03490         baseName.Buffer = (PWSTR) keyValueInformation;
    03491
    03492         RtlAppendUnicodeStringToString( &baseName, &prefixName );
    03493         RtlAppendUnicodeStringToString( &baseName, &fileName );
    03494
    03495         ExFreePool( keyBasicInformation );
    03496         keyBasicInformation = NULL;
    03497     }
    03498
    03499     //
    03500     // Now get the name of the driver object.
    03501     //
    03502
    03503     status = IopGetDriverNameFromKeyNode( KeyHandle,
    03504                                           &driverName );
    03505     if (!NT_SUCCESS( status )) {
    03506         goto IopLoadExit;
    03507     }
    03508
    03509     InitializeObjectAttributes( &objectAttributes,
    03510                                 &driverName,
    03511                                 OBJ_PERMANENT,
    03512                                 (HANDLE) NULL,
    03513                                 (PSECURITY_DESCRIPTOR) NULL );
    03514
    03515     //
    03516     // Load the driver image into memory.  If this fails partway through
    03517     // the operation, then it will automatically be unloaded.
    03518     //
    03519
    03520     status = MmLoadSystemImage( &baseName,
    03521                                 NULL,
    03522                                 NULL,
    03523                                 FALSE,
    03524                                 &sectionPointer,
    03525                                 (PVOID *) &imageBaseAddress );
    03526
    03527     if (!NT_SUCCESS( status )) {
    03528
    03529         //
    03530         // If the image was not already loaded then exit.
    03531         //
    03532
    03533         if (status != STATUS_IMAGE_ALREADY_LOADED) {
    03534
    03535             IopBootLog(&baseName, FALSE);
    03536
    03537             goto IopLoadExit;
    03538         }
    03539
    03540         //
    03541         // Open the driver object.
    03542         //
    03543
    03544         status = ObOpenObjectByName( &objectAttributes,
    03545                                      IoDriverObjectType,
    03546                                      KernelMode,
    03547                                      NULL,
    03548                                      0,
    03549                                      NULL,
    03550                                      &driverHandle );
    03551
    03552
    03553         if (!NT_SUCCESS( status )) {
    03554
    03555             IopBootLog(&baseName, FALSE);
    03556
    03557             goto IopLoadExit;
    03558         }
    03559
    03560         //
    03561         // Reference the handle and obtain a pointer to the driver object so that
    03562         // the handle can be deleted without the object going away.
    03563         //
    03564
    03565         status = ObReferenceObjectByHandle( driverHandle,
    03566                                             0,
    03567                                             IoDriverObjectType,
    03568                                             KeGetPreviousMode(),
    03569                                             (PVOID *) &driverObject,
    03570                                             (POBJECT_HANDLE_INFORMATION) NULL );
    03571
    03572         NtClose( driverHandle );
    03573
    03574         if (!NT_SUCCESS( status )) {
    03575             IopBootLog(&baseName, FALSE);
    03576             goto IopLoadExit;
    03577         }
    03578
    03579         status = IopResurrectDriver( driverObject );
    03580
    03581         //
    03582         // Regardless of the status the driver object should be dereferenced.
    03583         // if the unload has already run then driver is almost gone. If
    03584         // the driver has been resurrected then the I/O system still has its
    03585         // original reference.
    03586         //
    03587
    03588         ObDereferenceObject( driverObject );
    03589         IopBootLog(&baseName, FALSE);
    03590         goto IopLoadExit;
    03591     } else {
    03592
    03593         ntHeaders = RtlImageNtHeader( imageBaseAddress );
    03594
    03595         //
    03596         // Check should this driver be loaded.  If yes, the enum subkey
    03597         // of the service will be prepared.
    03598         //
    03599
    03600         status = IopPrepareDriverLoading (&serviceName, KeyHandle, ntHeaders);
    03601         if (!NT_SUCCESS(status)) {
    03602             MmUnloadSystemImage(sectionPointer);
    03603             IopBootLog(&baseName, FALSE);
    03604             goto IopLoadExit;
    03605         }
    03606
    03607     }
    03608
    03609     //
    03610     // The driver image has now been loaded into memory.  Create the driver
    03611     // object that represents this image.
    03612     //
    03613
    03614     status = ObCreateObject( KeGetPreviousMode(),
    03615                              IoDriverObjectType,
    03616                              &objectAttributes,
    03617                              KernelMode,
    03618                              (PVOID) NULL,
    03619                              (ULONG) (sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION )),
    03620                              0,
    03621                              0,
    03622                              (PVOID *) &driverObject );
    03623
    03624     if (!NT_SUCCESS( status )) {
    03625         IopBootLog(&baseName, FALSE);
    03626         goto IopLoadExit;
    03627     }
    03628
    03629     //
    03630     // Initialize this driver object and insert it into the object table.
    03631     //
    03632
    03633     RtlZeroMemory( driverObject, sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION) );
    03634     driverObject->DriverExtension = (PDRIVER_EXTENSION) (driverObject + 1);
    03635     driverObject->DriverExtension->DriverObject = driverObject;
    03636
    03637     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
    03638         driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
    03639     }
    03640
    03641     driverObject->Type = IO_TYPE_DRIVER;
    03642     driverObject->Size = sizeof( DRIVER_OBJECT );
    03643     ntHeaders = RtlImageNtHeader( imageBaseAddress );
    03644     entryPoint = ntHeaders->OptionalHeader.AddressOfEntryPoint;
    03645     entryPoint += (ULONG_PTR) imageBaseAddress;
    03646     if (!(ntHeaders->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)) {
    03647         driverObject->Flags |= DRVO_LEGACY_DRIVER;
    03648     }
    03649     driverObject->DriverInit = (PDRIVER_INITIALIZE) entryPoint;
    03650     driverObject->DriverSection = sectionPointer;
    03651     driverObject->DriverStart = imageBaseAddress;
    03652     driverObject->DriverSize = ntHeaders->OptionalHeader.SizeOfImage;
    03653
    03654     status = ObInsertObject( driverObject,
    03655                              (PACCESS_STATE) NULL,
    03656                              FILE_READ_DATA,
    03657                              0,
    03658                              (PVOID *) NULL,
    03659                              &driverHandle );
    03660     if (!NT_SUCCESS( status )) {
    03661         IopBootLog(&baseName, FALSE);
    03662         goto IopLoadExit;
    03663     }
    03664
    03665     //
    03666     // Reference the handle and obtain a pointer to the driver object so that
    03667     // the handle can be deleted without the object going away.
    03668     //
    03669
    03670     status = ObReferenceObjectByHandle( driverHandle,
    03671                                         0,
    03672                                         IoDriverObjectType,
    03673                                         KeGetPreviousMode(),
    03674                                         (PVOID *) &driverObject,
    03675                                         (POBJECT_HANDLE_INFORMATION) NULL );
    03676
    03677     NtClose( driverHandle );
    03678
    03679     //
    03680     // Load the Registry information in the appropriate fields of the device
    03681     // object.
    03682     //
    03683
    03684     driverObject->HardwareDatabase =
    03685         &CmRegistryMachineHardwareDescriptionSystemName;
    03686
    03687     //
    03688     // Store the name of the device driver in the driver object so that it
    03689     // can be easily found by the error log thread.
    03690     //
    03691
    03692     driverObject->DriverName.Buffer = ExAllocatePool( PagedPool,
    03693                                                       driverName.MaximumLength );
    03694     if (driverObject->DriverName.Buffer) {
    03695         driverObject->DriverName.MaximumLength = driverName.MaximumLength;
    03696         driverObject->DriverName.Length = driverName.Length;
    03697
    03698         RtlCopyMemory( driverObject->DriverName.Buffer,
    03699                        driverName.Buffer,
    03700                        driverName.MaximumLength );
    03701     }
    03702
    03703     //
    03704     // Query the name of the registry path for this driver so that it can
    03705     // be passed to the driver.
    03706     //
    03707
    03708     registryPath = ExAllocatePool( NonPagedPool, PAGE_SIZE );
    03709     if (!registryPath) {
    03710         ObMakeTemporaryObject( driverObject );
    03711         ObDereferenceObject( driverObject );
    03712         status = STATUS_INSUFFICIENT_RESOURCES;
    03713         goto IopLoadExit;
    03714     }
    03715
    03716     status = NtQueryObject( KeyHandle,
    03717                             ObjectNameInformation,
    03718                             registryPath,
    03719                             PAGE_SIZE,
    03720                             &i );
    03721     if (!NT_SUCCESS( status )) {
    03722         ObMakeTemporaryObject( driverObject );
    03723         ObDereferenceObject( driverObject );
    03724         ExFreePool( registryPath );
    03725         goto IopLoadExit;
    03726     }
    03727
    03728 #if DBG
    03729     KeQuerySystemTime (&stime);
    03730 #endif
    03731
    03732     //
    03733     // Store the service key name of the device driver in the driver object
    03734     //
    03735
    03736     if (serviceName.Buffer) {
    03737         driverObject->DriverExtension->ServiceKeyName.Buffer =
    03738             ExAllocatePool( NonPagedPool, serviceName.MaximumLength );
    03739         if (driverObject->DriverExtension->ServiceKeyName.Buffer) {
    03740             driverObject->DriverExtension->ServiceKeyName.MaximumLength = serviceName.MaximumLength;
    03741             driverObject->DriverExtension->ServiceKeyName.Length = serviceName.Length;
    03742
    03743             RtlCopyMemory( driverObject->DriverExtension->ServiceKeyName.Buffer,
    03744                            serviceName.Buffer,
    03745                            serviceName.MaximumLength );
    03746         }
    03747     }
    03748
    03749     //
    03750     // Now invoke the driver's initialization routine to initialize itself.
    03751     //
    03752
    03753     PERFINFO_DRIVER_INIT(driverObject);
    03754
    03755     status = driverObject->DriverInit( driverObject, &registryPath->Name );
    03756
    03757     PERFINFO_DRIVER_INIT_COMPLETE(driverObject);
    03758
    03759 #if DBG
    03760
    03761     //
    03762     // If DriverInit took longer than 5 seconds, print a message.
    03763     //
    03764
    03765     KeQuerySystemTime (&etime);
    03766     dtime  = (ULONG) ((etime.QuadPart - stime.QuadPart) / 1000000);
    03767
    03768     if (dtime > 50) {
    03769         DbgPrint( "IOLOAD: Driver %wZ took %d.%ds to %s\n",
    03770             &driverName,
    03771             dtime/10,
    03772             dtime%10,
    03773             NT_SUCCESS(status) ? "initialize" : "fail initialization"
    03774             );
    03775
    03776     }
    03777 #endif
    03778
    03779     //
    03780     // Workaround for broken NT 4.0 3D labs driver
    03781     // They zero out some function table entries by mistake.
    03782
    03783     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
    03784         if (driverObject->MajorFunction[i] == NULL) {
    03785             ASSERT(driverObject->MajorFunction[i] != NULL);
    03786             driverObject->MajorFunction[i] = IopInvalidDeviceRequest;
    03787         }
    03788     }
    03789
    03790     //
    03791     // If DriverInit doesn't work, then simply unload the image and mark the driver
    03792     // object as temporary.  This will cause everything to be deleted.
    03793     //
    03794
    03795     ExFreePool( registryPath );
    03796
    03797     //
    03798     // If we load the driver because we think it is a legacy driver and
    03799     // it does not create any device object in its DriverEntry.  We will
    03800     // unload this driver.
    03801     //
    03802
    03803     if (NT_SUCCESS(status) && !IopIsLegacyDriver(driverObject)) {
    03804         if (driverObject->DeviceObject == NULL &&
    03805             serviceName.Buffer &&
    03806             !IopIsAnyDeviceInstanceEnabled(&serviceName, NULL, FALSE) &&
    03807             !(driverObject->Flags & DRVO_REINIT_REGISTERED)) {
    03808             IopDriverLoadingFailed(KeyHandle, NULL);
    03809             status = STATUS_PLUGPLAY_NO_DEVICE;
    03810         } else {
    03811
    03812             //
    03813             // Start the devices controlled by the driver and enumerate them
    03814             // At this point, we know there is at least one device controlled by the driver.
    03815             //
    03816
    03817             IopDeleteLegacyKey(driverObject);
    03818             if (PnPInitialized) {
    03819                 status = IopStartDriverDevices(driverObject);
    03820             }
    03821         }
    03822         if (!NT_SUCCESS(status)) {
    03823             if (driverObject->DriverUnload) {
    03824                 driverObject->Flags |= DRVO_UNLOAD_INVOKED;
    03825                 driverObject->DriverUnload(driverObject);
    03826                 IopBootLog(&baseName, FALSE);
    03827             } else {
    03828     #if DBG
    03829                 DbgPrint("IopLoadDriver: A PnP driver %wZ does not support DriverUnload routine.\n", &driverName);
    03830                 // ASSERT(0);
    03831     #endif
    03832             }
    03833         }
    03834     }
    03835
    03836     if (!NT_SUCCESS( status )) {
    03837         ObMakeTemporaryObject( driverObject );
    03838         ObDereferenceObject( driverObject );
    03839     } else {
    03840
    03841         //
    03842         // Free the memory occupied by the driver's initialization routines.
    03843         //
    03844
    03845         IopBootLog(&baseName, TRUE);
    03846         MmFreeDriverInitialization( driverObject->DriverSection );
    03847         IopReadyDeviceObjects( driverObject );
    03848     }
    03849
    03850 IopLoadExit:
    03851
    03852     //
    03853     // Free any pool that was allocated by this routine that has not yet
    03854     // been freed.
    03855     //
    03856
    03857     if (driverName.Buffer != NULL) {
    03858         ExFreePool( driverName.Buffer );
    03859     }
    03860
    03861     if (keyValueInformation != NULL) {
    03862         ExFreePool( keyValueInformation );
    03863     }
    03864
    03865     if (keyBasicInformation != NULL) {
    03866         ExFreePool( keyBasicInformation );
    03867     }
    03868
    03869     if (serviceName.Buffer != NULL) {
    03870         ExFreePool(serviceName.Buffer);
    03871     }
    03872
    03873     //
    03874     // If this routine is about to return a failure, then let the Configuration
    03875     // Manager know about it.  But, if STATUS_PLUGPLAY_NO_DEVICE, the device was
    03876     // disabled by hardware profile.  In this case we don't need to report it.
    03877     //
    03878
    03879     if (!NT_SUCCESS( status ) && (status != STATUS_PLUGPLAY_NO_DEVICE)) {
    03880
    03881         NTSTATUS lStatus;
    03882         PULONG errorControl;
    03883
    03884         if (status != STATUS_IMAGE_ALREADY_LOADED) {
    03885
    03886             //
    03887             // If driver was loaded, do not call IopDriverLoadingFailed to change
    03888             // the driver loading status.  Because, obviously, the driver is
    03889             // running.
    03890             //
    03891
    03892             IopDriverLoadingFailed(KeyHandle, NULL);
    03893             lStatus = IopGetRegistryValue( KeyHandle,
    03894                                            L"ErrorControl",
    03895                                            &keyValueInformation );
    03896             if (!NT_SUCCESS( lStatus ) || !keyValueInformation->DataLength) {
    03897                 if (NT_SUCCESS( lStatus )) {
    03898                     ExFreePool( keyValueInformation );
    03899                 }
    03900             } else {
    03901                 errorControl = (PULONG) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset);
    03902                 CmBootLastKnownGood( *errorControl );
    03903                 ExFreePool( keyValueInformation );
    03904             }
    03905         }
    03906     }
    03907
    03908     //
    03909     // Close the caller's handle and return the final status from the load
    03910     // operation.
    03911     //
    03912
    03913     NtClose( KeyHandle );
    03914     return status;
    03915 }

VOID IopLoadFileSystemDriver | ( | IN PDEVICE_OBJECT | DeviceObject | ) |

Definition at line 4077 of file internal.c.

References _DEVICE_OBJECT::AttachedDevice, Executive, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, IoGetNextIrpStackLocation, IopDecrementDeviceObjectRef(), IRP_MJ_DEVICE_CONTROL, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_LOAD_FILE_SYSTEM, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, PAGED_CODE, TRUE, and VOID().

Referenced by IopMountVolume().

    04083                    :
    04084
    04085     This routine is invoked when a mini-file system recognizer driver recognizes
    04086     a volume as being a particular file system, but the driver for that file
    04087     system has not yet been loaded.  This function allows the mini-driver to
    04088     load the real file system, and remove itself from the system, so that the
    04089     real file system can mount the device in question.
    04090
    04091 Arguments:
    04092
    04093     DeviceObject - Registered file system device object for the mini-driver.
    04094
    04095 Return Value:
    04096
    04097     None.
    04098
    04099 --*/
    04100
    04101 {
    04102     KEVENT event;
    04103     NTSTATUS status;
    04104     IO_STATUS_BLOCK ioStatus;
    04105     PIRP irp;
    04106     PIO_STACK_LOCATION irpSp;
    04107     PDEVICE_OBJECT attachedDevice;
    04108
    04109     PAGED_CODE();
    04110
    04111     attachedDevice = DeviceObject;
    04112     while (attachedDevice->AttachedDevice) {
    04113         attachedDevice = attachedDevice->AttachedDevice;
    04114     }
    04115
    04116     //
    04117     // Begin by building an I/O Request Packet to have the mini-file system
    04118     // driver load the real file system.
    04119     //
    04120
    04121     KeInitializeEvent( &event, NotificationEvent, FALSE );
    04122
    04123     irp = IoBuildDeviceIoControlRequest( IRP_MJ_DEVICE_CONTROL,
    04124                                          attachedDevice,
    04125                                          (PVOID) NULL,
    04126                                          0,
    04127                                          (PVOID) NULL,
    04128                                          0,
    04129                                          FALSE,
    04130                                          &event,
    04131                                          &ioStatus );
    04132     if (irp) {
    04133
    04134         //
    04135         // Change the actual major and minor function codes to be a file system
    04136         // control with a minor function code of load FS driver.
    04137         //
    04138
    04139         irpSp = IoGetNextIrpStackLocation( irp );
    04140         irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
    04141         irpSp->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM;
    04142
    04143         //
    04144         // Now issue the request.
    04145         //
    04146
    04147         status = IoCallDriver( attachedDevice, irp );
    04148         if (status == STATUS_PENDING) {
    04149             (VOID) KeWaitForSingleObject( &event,
    04150                                           Executive,
    04151                                           KernelMode,
    04152                                           FALSE,
    04153                                           (PLARGE_INTEGER) NULL );
    04154         }
    04155     }
    04156
    04157     //
    04158     // Decrement the reference count on the device object.  If this is the last
    04159     // last reason that this mini-file system recognizer needs to stay around,
    04160     // then unload it.
    04161     //
    04162
    04163     IopDecrementDeviceObjectRef(DeviceObject, TRUE);
    04164
    04165     return;
    04166 }

VOID IopLoadUnloadDriver | ( | IN PVOID | Parameter | ) |

Definition at line 4169 of file internal.c.

References _REINIT_PACKET::Context, _DRIVER_EXTENSION::Count, _DRIVER_OBJECT::DriverExtension, _REINIT_PACKET::DriverObject, _LOAD_PACKET::DriverObject, _REINIT_PACKET::DriverReinitializationRoutine, _LOAD_PACKET::DriverServiceName, _DRIVER_OBJECT::DriverUnload, DRVO_REINIT_REGISTERED, _LOAD_PACKET::Event, ExFreePool(), ExInterlockedRemoveHeadList(), FALSE, _LOAD_PACKET::FinalStatus, _DRIVER_OBJECT::Flags, IopDatabaseLock, IopDriverReinitializeQueueHead, IopLoadDriver(), IopOpenRegistryKey(), KeSetEvent(), NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, PLOAD_PACKET, PREINIT_PACKET, REINIT_PACKET, TRUE, and VOID().

Referenced by IopCompleteUnloadOrDelete(), NtLoadDriver(), and NtUnloadDriver().

    04175                    :
    04176
    04177     This routine is executed as an EX worker thread routine when a driver is
    04178     to be loaded or unloaded dynamically.  It is used because some drivers
    04179     need to create system threads in the context of the system process, which
    04180     cannot be done in the context of the caller of the system service that
    04181     was invoked to load or unload the specified driver.
    04182
    04183 Arguments:
    04184
    04185     Parameter - Pointer to the load packet describing what work is to be
    04186         done.
    04187
    04188 Return Value:
    04189
    04190     None.
    04191
    04192 --*/
    04193
    04194 {
    04195     PLOAD_PACKET loadPacket;
    04196     NTSTATUS status;
    04197     HANDLE keyHandle;
    04198
    04199     PAGED_CODE();
    04200
    04201     //
    04202     // Begin by getting a pointer to the load packet.
    04203     //
    04204
    04205     loadPacket = (PLOAD_PACKET) Parameter;
    04206
    04207     //
    04208     // If the driver object field of the packet is non-NULL, then this is
    04209     // a request to complete the unload of a driver.  Simply invoke the
    04210     // driver's unload routine.  Note that the final status of the unload
    04211     // is ignored, so it is not set here.
    04212     //
    04213
    04214     if (loadPacket->DriverObject) {
    04215
    04216         loadPacket->DriverObject->DriverUnload( loadPacket->DriverObject );
    04217         status = STATUS_SUCCESS;
    04218
    04219     } else {
    04220
    04221         PLIST_ENTRY entry;
    04222         PREINIT_PACKET reinitEntry;
    04223
    04224         //
    04225         // The driver specified by the DriverServiceName is to be loaded.
    04226         // Begin by opening the registry node for this driver.  Note
    04227         // that if this is successful, then the load driver routine is
    04228         // responsible for closing the handle.
    04229         //
    04230
    04231         status = IopOpenRegistryKey( &keyHandle,
    04232                                      (HANDLE) NULL,
    04233                                      loadPacket->DriverServiceName,
    04234                                      KEY_READ,
    04235                                      FALSE );
    04236         if (NT_SUCCESS( status )) {
    04237
    04238             //
    04239             // Invoke the internal common routine to perform the work.
    04240             // This is the same routine that is used by the I/O system
    04241             // initialization code to load drivers.
    04242             //
    04243
    04244             status = IopLoadDriver( keyHandle, TRUE );
    04245
    04246             //
    04247             // Walk the list reinitialization list in case this driver, or
    04248             // some other driver, has requested to be invoked at a re-
    04249             // initialization entry point.
    04250             //
    04251
    04252             while (entry = ExInterlockedRemoveHeadList( &IopDriverReinitializeQueueHead, &IopDatabaseLock )) {
    04253                 reinitEntry = CONTAINING_RECORD( entry, REINIT_PACKET, ListEntry );
    04254 //#if _PNP_POWER_
    04255                 reinitEntry->DriverObject->DriverExtension->Count++;
    04256                 reinitEntry->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED;
    04257                 reinitEntry->DriverReinitializationRoutine( reinitEntry->DriverObject,
    04258                                                             reinitEntry->Context,
    04259                                                             reinitEntry->DriverObject->DriverExtension->Count );
    04260 //#else
    04261 #if 0
    04262                 reinitEntry->DriverObject->Count++;
    04263                 reinitEntry->DriverReinitializationRoutine( reinitEntry->DriverObject,
    04264                                                             reinitEntry->Context,
    04265                                                             reinitEntry->DriverObject->Count );
    04266 #endif // _PNP_POWER_
    04267                 ExFreePool( reinitEntry );
    04268             }
    04269         }
    04270     }
    04271
    04272     //
    04273     // Set the final status of the load or unload operation, and indicate to
    04274     // the caller that the operation is now complete.
    04275     //
    04276
    04277     loadPacket->FinalStatus = status;
    04278     (VOID) KeSetEvent( &loadPacket->Event, 0, FALSE );
    04279 }

NTSTATUS IopLogErrorEvent | ( | IN ULONG | SequenceNumber,
|  | IN ULONG | UniqueErrorValue,
|  | IN NTSTATUS | FinalStatus,
|  | IN NTSTATUS | SpecificIOStatus,
|  | IN ULONG | LengthOfInsert1,
|  | IN PWCHAR | Insert1,
|  | IN ULONG | LengthOfInsert2,
|  | IN PWCHAR | Insert2
| ) |

Definition at line 4393 of file ioinit.c.

References IoAllocateErrorLogEntry(), IopErrorLogObject, IoWriteErrorLogEntry(), NULL, and USHORT.

Referenced by IopCompleteDumpInitialization(), IopConfigureCrashDump(), IopGetDumpStack(), and IopInitializeDCB().

    04406                    :
    04407
    04408     This routine allocates an error log entry, copies the supplied data
    04409     to it, and requests that it be written to the error log file.
    04410
    04411 Arguments:
    04412     SequenceNumber - A value that is unique to an IRP over the life of the irp in
    04413     this driver. - 0 generally means an error not associated with an IRP
    04414
    04415     UniqueErrorValue - A unique long word that identifies the particular
    04416     call to this function.
    04417
    04418     FinalStatus - The final status given to the irp that was associated
    04419     with this error.  If this log entry is being made during one of
    04420     the retries this value will be STATUS_SUCCESS.
    04421
    04422     SpecificIOStatus - The IO status for a particular error.
    04423
    04424     LengthOfInsert1 - The length in bytes (including the terminating NULL)
    04425                       of the first insertion string.
    04426
    04427     Insert1 - The first insertion string.
    04428
    04429     LengthOfInsert2 - The length in bytes (including the terminating NULL)
    04430                       of the second insertion string.  NOTE, there must
    04431                       be a first insertion string for their to be
    04432                       a second insertion string.
    04433
    04434     Insert2 - The second insertion string.
    04435
    04436 Return Value:
    04437
    04438     STATUS_SUCCESS - Success
    04439     STATUS_INVALID_HANDLE - Uninitialized error log device object
    04440     STATUS_NO_DATA_DETECTED - NULL Error log entry
    04441
    04442 --*/
    04443
    04444 {
    04445     PIO_ERROR_LOG_PACKET errorLogEntry;
    04446     PUCHAR ptrToFirstInsert;
    04447     PUCHAR ptrToSecondInsert;
    04448
    04449     if (!IopErrorLogObject) {
    04450         return(STATUS_INVALID_HANDLE);
    04451     }
    04452
    04453
    04454     errorLogEntry = IoAllocateErrorLogEntry(
    04455                         IopErrorLogObject,
    04456                         (UCHAR)( sizeof(IO_ERROR_LOG_PACKET) +
    04457                                 LengthOfInsert1 +
    04458                                 LengthOfInsert2) );
    04459
    04460    if ( errorLogEntry != NULL ) {
    04461
    04462       errorLogEntry->ErrorCode = SpecificIOStatus;
    04463       errorLogEntry->SequenceNumber = SequenceNumber;
    04464       errorLogEntry->MajorFunctionCode = 0;
    04465       errorLogEntry->RetryCount = 0;
    04466       errorLogEntry->UniqueErrorValue = UniqueErrorValue;
    04467       errorLogEntry->FinalStatus = FinalStatus;
    04468       errorLogEntry->DumpDataSize = 0;
    04469
    04470       ptrToFirstInsert = (PUCHAR)&errorLogEntry->DumpData[0];
    04471
    04472       ptrToSecondInsert = ptrToFirstInsert + LengthOfInsert1;
    04473
    04474       if (LengthOfInsert1) {
    04475
    04476          errorLogEntry->NumberOfStrings = 1;
    04477          errorLogEntry->StringOffset = (USHORT)(ptrToFirstInsert -
    04478                                                 (PUCHAR)errorLogEntry);
    04479          RtlCopyMemory(
    04480                       ptrToFirstInsert,
    04481                       Insert1,
    04482                       LengthOfInsert1
    04483                       );
    04484
    04485          if (LengthOfInsert2) {
    04486
    04487             errorLogEntry->NumberOfStrings = 2;
    04488             RtlCopyMemory(
    04489                          ptrToSecondInsert,
    04490                          Insert2,
    04491                          LengthOfInsert2
    04492                          );
    04493
    04494          } //LenghtOfInsert2
    04495
    04496       } // LenghtOfInsert1
    04497
    04498       IoWriteErrorLogEntry(errorLogEntry);
    04499       return(STATUS_SUCCESS);
    04500
    04501    }  // errorLogEntry != NULL
    04502
    04503     return(STATUS_NO_DATA_DETECTED);
    04504
    04505 } //IopLogErrorEvent

NTSTATUS IopLookupBusStringFromID | ( | IN HANDLE | KeyHandle,
|  | IN INTERFACE_TYPE | InterfaceType,
|  | OUT PWCHAR | Buffer,
|  | IN ULONG | Length,
|  | OUT PULONG BusFlags | OPTIONAL
| ) |

Definition at line 8729 of file internal.c.

References Buffer, c, Index, InterfaceType, NT_SUCCESS, NTSTATUS(), and PAGED_CODE.

    08738                    :
    08739
    08740     Translates INTERFACE_TYPE to its corresponding WCHAR[] string.
    08741
    08742 Arguments:
    08743
    08744     KeyHandle - Supplies a handle to the opened registry key,
    08745         HKLM\System\CurrentControlSet\Control\SystemResources\BusValues.
    08746
    08747     InterfaceType - Supplies the interface type for which a descriptive
    08748         name is to be retrieved.
    08749
    08750     Buffer - Supplies a pointer to a unicode character buffer that will
    08751         receive the bus name.  Since this buffer is used in an
    08752         intermediate step to retrieve a KEY_VALUE_FULL_INFORMATION structure,
    08753         it must be large enough to contain this structure (including the
    08754         longest value name & data length under KeyHandle).
    08755
    08756     Length - Supplies the length, in bytes, of the Buffer.
    08757
    08758     BusFlags - Optionally receives the flags specified in the second
    08759         DWORD of the matching REG_BINARY value.
    08760
    08761 Return Value:
    08762
    08763     The function value is the final status of the operation.
    08764
    08765 --*/
    08766 {
    08767     NTSTATUS                        status;
    08768     ULONG                           Index, junk, i, j;
    08769     PULONG                          pl;
    08770     PKEY_VALUE_FULL_INFORMATION     KeyInformation;
    08771     WCHAR                           c;
    08772
    08773     PAGED_CODE();
    08774
    08775     Index = 0;
    08776     KeyInformation = (PKEY_VALUE_FULL_INFORMATION) Buffer;
    08777
    08778     for (; ;) {
    08779         status = ZwEnumerateValueKey (
    08780                         KeyHandle,
    08781                         Index++,
    08782                         KeyValueFullInformation,
    08783                         Buffer,
    08784                         Length,
    08785                         &junk
    08786                         );
    08787
    08788         if (!NT_SUCCESS (status)) {
    08789             return status;
    08790         }
    08791
    08792         if (KeyInformation->Type != REG_BINARY) {
    08793             continue;
    08794         }
    08795
    08796         pl = (PULONG) ((PUCHAR) KeyInformation + KeyInformation->DataOffset);
    08797         if ((ULONG) InterfaceType != pl[0]) {
    08798             continue;
    08799         }
    08800
    08801         //
    08802         // Found a match - move the name to the start of the buffer
    08803         //
    08804
    08805         if(ARGUMENT_PRESENT(BusFlags)) {
    08806             *BusFlags = pl[1];
    08807         }
    08808
    08809         j = KeyInformation->NameLength / sizeof (WCHAR);
    08810         for (i=0; i < j; i++) {
    08811             c = KeyInformation->Name[i];
    08812             Buffer[i] = c;
    08813         }
    08814
    08815         Buffer[i] = 0;
    08816         return STATUS_SUCCESS;
    08817     }
    08818 }

NTSTATUS IopMountVolume | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN BOOLEAN | AllowRawMount,
|  | IN BOOLEAN | DeviceLockAlreadyHeld,
|  | IN BOOLEAN | Alertable
| ) |

Definition at line 4282 of file internal.c.

References _DEVICE_OBJECT::AttachedDevice, DO_SYSTEM_BOOT_PARTITION, DO_VERIFY_VOLUME, dummy(), ExAcquireResourceShared, Executive, ExInterlockedAddUlong(), ExReleaseResource, FALSE, _IO_STACK_LOCATION::Flags, _IRP::Flags, FsRtlIsTotalDeviceFailure(), InitializationPhase, IoCallDriver, IoGetNextIrpStackLocation, IoIsErrorUserInduced, IOP_ABORT, IopAllocateIrpMustSucceed(), IopCdRomFileSystemQueueHead, IopDatabaseLock, IopDatabaseResource, IopDiskFileSystemQueueHead, IopLoadFileSystemDriver(), IopTapeFileSystemQueueHead, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_MOUNT_VOLUME, IRP_MOUNT_COMPLETION, IRP_SYNCHRONOUS_PAGING_IO, KeBugCheckEx(), KeClearEvent, KeInitializeEvent, KernelMode, KeSetEvent(), KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PsGetCurrentThread, _DEVICE_OBJECT::ReferenceCount, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserEvent, _IRP::UserIosb, VOID(), VPB_MOUNTED, VPB_RAW_MOUNT, and VPB_REMOVE_PENDING.

Referenced by IopCheckVpbMounted(), and IoVerifyVolume().

    04291                    :
    04292
    04293     This routine is used to mount a volume on the specified device.  The Volume
    04294     Parameter Block (VPB) for the specified device is a "clean" VPB.  That is,
    04295     it indicates that the volume has never been mounted.  It is up to the file
    04296     system that eventually mounts the volume to determine whether the volume is,
    04297     or has been, mounted elsewhere.
    04298
    04299 Arguments:
    04300
    04301     DeviceObject - Pointer to device object on which the volume is to be
    04302         mounted.
    04303
    04304     AllowRawMount - This parameter tells us if we should continue our
    04305         filesystem search to include the Raw file system.  This flag will
    04306         only be passed in as TRUE as a result of a DASD open.
    04307
    04308     DeviceLockAlreadyHeld - If TRUE, then the caller has already acquired
    04309         the device lock and we should not attempt to acquire it.  This is
    04310         currently passed in as TRUE when called from IoVerifyVolume.
    04311
    04312 Return Value:
    04313
    04314     The function value is a successful status code if a volume was successfully
    04315     mounted on the device.  Otherwise, an error code is returned.
    04316
    04317
    04318 --*/
    04319
    04320 {
    04321     NTSTATUS status;
    04322     KEVENT event;
    04323     PIRP irp;
    04324     PDEVICE_OBJECT fsDeviceObject;
    04325     PDEVICE_OBJECT attachedDevice;
    04326     PLIST_ENTRY entry;
    04327     PLIST_ENTRY queueHeader;
    04328     IO_STATUS_BLOCK ioStatus;
    04329     PIO_STACK_LOCATION irpSp;
    04330     ULONG extraStack;
    04331     LIST_ENTRY dummy;
    04332     ULONG rawMountOnly;
    04333
    04334     PAGED_CODE();
    04335
    04336     //
    04337     // Obtain the lock for the device to be mounted.  This guarantees that
    04338     // only one thread is attempting to mount (or verify) this particular
    04339     // device at a time.
    04340     //
    04341
    04342     if (!DeviceLockAlreadyHeld) {
    04343
    04344         status = KeWaitForSingleObject( &DeviceObject->DeviceLock,
    04345                                         Executive,
    04346                                         KeGetPreviousMode(),
    04347                                         Alertable,
    04348                                         (PLARGE_INTEGER) NULL );
    04349
    04350         //
    04351         // If the wait ended because of an alert or an APC, return now
    04352         // without mounting the device.  Note that as the wait for the
    04353         // event was unsuccessful, we do not set it on exit.
    04354         //
    04355
    04356         if (status == STATUS_ALERTED || status == STATUS_USER_APC) {
    04357
    04358             return status;
    04359         }
    04360     }
    04361
    04362     //
    04363     // Now acquire the resource database lock for the I/O system to perform this
    04364     // operation.  This resource protects access to the file system queue.
    04365     //
    04366
    04367     //KeEnterCriticalRegion();
    04368     (VOID) ExAcquireResourceShared( &IopDatabaseResource, TRUE );
    04369
    04370     //
    04371     // Check the 'mounted' flag of the VPB to ensure that it is still clear.
    04372     // If it is, then no one has gotten in before this to mount the volume.
    04373     // Attempt to mount the volume in this case.
    04374     //
    04375
    04376     if ((DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)) == 0) {
    04377
    04378         //
    04379         // This volume has never been mounted.  Initialize the event and set the
    04380         // status to unsuccessful to set up for the loop.  Also if the device
    04381         // has the verify bit set, clear it.
    04382         //
    04383
    04384         KeInitializeEvent( &event, NotificationEvent, FALSE );
    04385         status = STATUS_UNSUCCESSFUL;
    04386         DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
    04387
    04388         //
    04389         // Get the actual device that this volume is to be mounted on.  This
    04390         // device is the final device in the list of devices which are attached
    04391         // to the specified real device.
    04392         //
    04393
    04394         attachedDevice = DeviceObject;
    04395         while (attachedDevice->AttachedDevice) {
    04396             attachedDevice = attachedDevice->AttachedDevice;
    04397         }
    04398
    04399         //
    04400         // Reference the device object so it cannot go away.
    04401         //
    04402
    04403         ObReferenceObject( attachedDevice );
    04404
    04405         //
    04406         // Determine which type of file system should be invoked based on
    04407         // the device type of the device being mounted.
    04408         //
    04409
    04410         if (DeviceObject->DeviceType == FILE_DEVICE_DISK ||
    04411             DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK) {
    04412             queueHeader = &IopDiskFileSystemQueueHead;
    04413         } else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM) {
    04414             queueHeader = &IopCdRomFileSystemQueueHead;
    04415         } else {
    04416             queueHeader = &IopTapeFileSystemQueueHead;
    04417         }
    04418
    04419         rawMountOnly = (DeviceObject->Vpb->Flags & VPB_RAW_MOUNT);
    04420
    04421         //
    04422         // Now loop through each of the file systems which have been loaded in
    04423         // the system to see whether anyone understands the media in the device.
    04424         //
    04425
    04426         for (entry = queueHeader->Flink;
    04427              entry != queueHeader && !NT_SUCCESS( status );
    04428              entry = entry->Flink) {
    04429
    04430             PDEVICE_OBJECT savedFsDeviceObject;
    04431
    04432             //
    04433             // If this is the final entry (Raw file system), and it is also
    04434             // not the first entry, and a raw mount is not permitted, then
    04435             // break out of the loop at this point, as this volume cannot
    04436             // be mounted for the caller's purposes.
    04437             //
    04438
    04439             if (!AllowRawMount && entry->Flink == queueHeader && entry != queueHeader->Flink) {
    04440                 break;
    04441             }
    04442
    04443             //
    04444             // If raw mount is the only one requested and this is not the last entry on the list
    04445             // then skip.
    04446             //
    04447             if (rawMountOnly && (entry->Flink != queueHeader)) {
    04448                 continue;
    04449             }
    04450
    04451             fsDeviceObject = CONTAINING_RECORD( entry, DEVICE_OBJECT, Queue.ListEntry );
    04452             savedFsDeviceObject = fsDeviceObject;
    04453
    04454             //
    04455             // It is possible that the file system has been attached to, so
    04456             // walk the attached list for the file system.  The number of stack
    04457             // locations that must be allocated in the IRP must include one for
    04458             // the file system itself, and then one for each driver that is
    04459             // attached to it.  Account for all of the stack locations required
    04460             // to get through the mount process.
    04461             //
    04462
    04463             extraStack = 1;
    04464
    04465             while (fsDeviceObject->AttachedDevice) {
    04466                 fsDeviceObject = fsDeviceObject->AttachedDevice;
    04467                 extraStack++;
    04468             }
    04469
    04470             //
    04471             // Another file system has been found and the volume has still not
    04472             // been mounted.  Attempt to mount the volume using this file
    04473             // system.
    04474             //
    04475             // Begin by resetting the event being used for synchronization with
    04476             // the I/O operation.
    04477             //
    04478
    04479             KeClearEvent( &event );
    04480
    04481             //
    04482             // Allocate and initialize an IRP for this mount operation.  Notice
    04483             // that the flags for this operation appear the same as a page read
    04484             // operation.  This is because the completion code for both of the
    04485             // operations is exactly the same logic.
    04486             //
    04487
    04488             irp = IopAllocateIrpMustSucceed( (CCHAR) (attachedDevice->StackSize + extraStack) );
    04489             irp->Flags = IRP_MOUNT_COMPLETION | IRP_SYNCHRONOUS_PAGING_IO;
    04490             irp->RequestorMode = KernelMode;
    04491             irp->UserEvent = &event;
    04492             irp->UserIosb = &ioStatus;
    04493             irp->Tail.Overlay.Thread = PsGetCurrentThread();
    04494             irpSp = IoGetNextIrpStackLocation( irp );
    04495             irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
    04496             irpSp->MinorFunction = IRP_MN_MOUNT_VOLUME;
    04497             irpSp->Flags = AllowRawMount;
    04498             irpSp->Parameters.MountVolume.Vpb = DeviceObject->Vpb;
    04499             irpSp->Parameters.MountVolume.DeviceObject = attachedDevice;
    04500
    04501             status = IoCallDriver( fsDeviceObject, irp );
    04502
    04503             //
    04504             // Wait for the I/O operation to complete.
    04505             //
    04506
    04507             if (NT_SUCCESS( status )) {
    04508                 (VOID) KeWaitForSingleObject( &event,
    04509                                               Executive,
    04510                                               KernelMode,
    04511                                               FALSE,
    04512                                               (PLARGE_INTEGER) NULL );
    04513             } else {
    04514
    04515                 //
    04516                 // Ensure that the proper status value gets picked up.
    04517                 //
    04518
    04519                 ioStatus.Status = status;
    04520                 ioStatus.Information = 0;
    04521             }
    04522
    04523             //
    04524             // If the operation was successful then set the VPB as mounted.
    04525             //
    04526
    04527             if (NT_SUCCESS( ioStatus.Status )) {
    04528                 status = ioStatus.Status;
    04529                 DeviceObject->Vpb->Flags = VPB_MOUNTED;
    04530
    04531                 //
    04532                 // We explicitly propagate VPB_RAW_MOUNT as the previous
    04533                 // statement that has been there for a long time in NT
    04534                 // could be clearing other flags which should be cleared.
    04535                 //
    04536                 if (rawMountOnly) {
    04537                     DeviceObject->Vpb->Flags |= VPB_RAW_MOUNT;
    04538                 }
    04539                 DeviceObject->Vpb->DeviceObject->StackSize = (UCHAR) (attachedDevice->StackSize + 1);
    04540
    04541             } else {
    04542
    04543                 //
    04544                 // The mount operation failed.  Make a special check here to
    04545                 // determine whether or not a popup was enabled, and if so,
    04546                 // check to see whether or not the operation was to be aborted.
    04547                 // If so, bail out now and return the error to the caller.
    04548                 //
    04549
    04550                 status = ioStatus.Status;
    04551                 if (IoIsErrorUserInduced(status) &&
    04552                     ioStatus.Information == IOP_ABORT) {
    04553                     break;
    04554                 }
    04555
    04556                 //
    04557                 // Also check to see whether or not this is a volume that has
    04558                 // been recognized, but the file system for it needs to be
    04559                 // loaded.  If so, drop the locks held at this point, tell the
    04560                 // mini-file system recognizer to load the driver, and then
    04561                 // reacquire the locks.
    04562                 //
    04563
    04564                 if (status == STATUS_FS_DRIVER_REQUIRED) {
    04565
    04566                     //
    04567                     // Increment the number of reasons that this driver cannot
    04568                     // be unloaded.  Note that this must be done while still
    04569                     // holding the database resource.
    04570                     //
    04571
    04572                     ExInterlockedAddUlong( &savedFsDeviceObject->ReferenceCount,
    04573                                            1,
    04574                                            &IopDatabaseLock );
    04575
    04576                     //
    04577                     // Release the locks, load the new file system, and unload
    04578                     // the recognizer.
    04579                     //
    04580
    04581                     ExReleaseResource( &IopDatabaseResource );
    04582                     //KeLeaveCriticalRegion();
    04583                     if (!DeviceLockAlreadyHeld) {
    04584                         KeSetEvent( &DeviceObject->DeviceLock, 0, FALSE );
    04585                     }
    04586                     IopLoadFileSystemDriver( savedFsDeviceObject );
    04587
    04588                     //
    04589                     // Now reacquire the locks, in the correct order, and check
    04590                     // to see if the volume has been mounted before we could
    04591                     // get back.  If so, exit; otherwise, restart the file
    04592                     // file system queue scan from the beginning.
    04593                     //
    04594
    04595                     if (!DeviceLockAlreadyHeld) {
    04596                         status = KeWaitForSingleObject( &DeviceObject->DeviceLock,
    04597                                                         Executive,
    04598                                                         KeGetPreviousMode(),
    04599                                                         Alertable,
    04600                                                         (PLARGE_INTEGER) NULL );
    04601                         if (status == STATUS_ALERTED || status == STATUS_USER_APC) {
    04602
    04603                             //
    04604                             // The device was not mounted by us so
    04605                             // drop the reference before returning.
    04606                             //
    04607
    04608                             ObDereferenceObject( attachedDevice );
    04609
    04610                             return status;
    04611                         }
    04612                     }
    04613
    04614                     //KeEnterCriticalRegion();
    04615                     (VOID) ExAcquireResourceShared( &IopDatabaseResource, TRUE );
    04616
    04617                     if (DeviceObject->Vpb->Flags & VPB_MOUNTED) {
    04618
    04619                         //
    04620                         //  This volume was mounted before we got back.
    04621                         //
    04622
    04623                         status = STATUS_SUCCESS;
    04624                         break;
    04625                     }
    04626
    04627                     //
    04628                     // Reset the list back to the beginning and start over
    04629                     // again.
    04630                     //
    04631
    04632                     dummy.Flink = queueHeader->Flink;
    04633                     entry = &dummy;
    04634                     status = STATUS_UNRECOGNIZED_VOLUME;
    04635                 }
    04636
    04637                 //
    04638                 // If the error wasn't STATUS_UNRECOGNIZED_VOLUME, and this
    04639                 // request is not going to the Raw file system, then there
    04640                 // is no reason to continue looping.
    04641                 //
    04642
    04643                 if (!AllowRawMount && (status != STATUS_UNRECOGNIZED_VOLUME) &&
    04644                     FsRtlIsTotalDeviceFailure(status)) {
    04645                     break;
    04646                 }
    04647             }
    04648         }
    04649
    04650         if (!NT_SUCCESS(status)) {
    04651
    04652             //
    04653             // The device was not mounted by us so
    04654             // drop the reference.
    04655             //
    04656
    04657             ObDereferenceObject( attachedDevice );
    04658
    04659         }
    04660
    04661     } else if((DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING) != 0) {
    04662
    04663         //
    04664         // Pnp is attempting to remove this volume.  Don't allow the mount.
    04665         //
    04666
    04667         status = STATUS_DEVICE_DOES_NOT_EXIST;
    04668
    04669     } else {
    04670
    04671         //
    04672         // The volume for this device has already been mounted.  Return a
    04673         // success code.
    04674         //
    04675
    04676         status = STATUS_SUCCESS;
    04677     }
    04678
    04679     ExReleaseResource( &IopDatabaseResource );
    04680     //KeLeaveCriticalRegion();
    04681
    04682     //
    04683     // Release the I/O database resource lock and the synchronization event for
    04684     // the device.
    04685     //
    04686
    04687     if (!DeviceLockAlreadyHeld) {
    04688         KeSetEvent( &DeviceObject->DeviceLock, 0, FALSE );
    04689     }
    04690
    04691     //
    04692     // Finally, if the mount operation failed, and the target device is the
    04693     // boot partition, then bugcheck the system.  It is not possible for the
    04694     // system to run properly if the system's boot partition cannot be mounted.
    04695     //
    04696     // Note: Don't bugcheck if the system is already booted.
    04697     //
    04698
    04699     if (!NT_SUCCESS( status ) &&
    04700         DeviceObject->Flags & DO_SYSTEM_BOOT_PARTITION &&
    04701         InitializationPhase < 2) {
    04702         KeBugCheckEx( INACCESSIBLE_BOOT_DEVICE, (ULONG_PTR) DeviceObject, status, 0, 0 );
    04703     }
    04704
    04705     return status;
    04706 }

BOOLEAN IopNotifyPnpWhenChainDereferenced | ( | IN PDEVICE_OBJECT * | PhysicalDeviceObjects,
|  | IN ULONG | DeviceObjectCount,
|  | IN BOOLEAN | Query,
|  | OUT PDEVICE_OBJECT * | VetoingDevice
| ) |

Definition at line 4947 of file internal.c.

References ASSERT, _DEVICE_OBJECT::AttachedDevice, _DEVOBJ_EXTENSION::DeviceNode, _DEVICE_OBJECT::DeviceObjectExtension, DOE_REMOVE_PENDING, DOE_REMOVE_PROCESSED, _DEVOBJ_EXTENSION::ExtensionFlags, IopChainDereferenceComplete(), IopDatabaseLock, NULL, and _DEVICE_OBJECT::ReferenceCount.

    04956                    :
    04957
    04958     Called by PnP when processing a Surprise Removal or a Query Remove.
    04959
    04960     In the case of Surprise Removal this function will set DOE_REMOVE_PENDING
    04961     in the device extension flags of the each PDO and all its attached devices.
    04962     For each PDO (and its attachment chain) which currently has a zero
    04963     ReferenceCount DOE_REMOVE_PENDING is reset and DOE_REMOVE_PROCESSED is
    04964     set.  IopChainDereferenceComplete is then called to notify PnP that
    04965     this PDO is ready for removal.
    04966
    04967     Then as each remaining PDO and its attachment chain's ReferenceCount drops
    04968     to zero IopCheckUnloadOrDelete will call IopChainDereferenceComplete
    04969     (supplied by PnP).
    04970
    04971     In the case of Query Remove this function set DOE_REMOVE_PROCESSED on the
    04972     PDO and all its attached devices to prevent further opens.  It also checks
    04973     to see if the ReferenceCount for all the PDOs and their attached devices is
    04974     zero.  If so it leaves the DOE_REMOVE_PROCESSED set and returns FALSE.  If
    04975     not, it resets the DOE_REMOVE_PROCESSED on all the PDOs and their attached
    04976     devices and returns TRUE.
    04977
    04978 Arguments:
    04979
    04980     PhysicalDeviceObjects   List of PDEVICE_OBJECTs for all of the PDOs to be
    04981                             checked.
    04982
    04983     DeviceObjectCount       Count of PDEVICE_OBJECTs in PhysicalDeviceObjects.
    04984
    04985     Query                   TRUE if this is for a Query Remove.
    04986
    04987     VetoingDevice           Only used for Query Remove, Set to first PDO with a
    04988                             ReferenceCount not equal to zero.  This is used to
    04989                             provide feedback to the user as to why the query
    04990                             may have failed.
    04991
    04992
    04993 Return Value:
    04994
    04995     If Query is set then the return value is TRUE if there are outstanding
    04996     opens on any of the PDOs or the attached devices, otherwise FALSE is
    04997     returned.
    04998
    04999     If Query is NOT set then the return value is always TRUE.
    05000
    05001 --*/
    05002
    05003 {
    05004     PDEVOBJ_EXTENSION deviceExtension;
    05005     PDEVICE_OBJECT deviceObject;
    05006     PDEVICE_OBJECT attachedDeviceObject;
    05007     PDEVICE_NODE deviceNode;
    05008     ULONG referenced;
    05009     ULONG pass1SetFlag;
    05010     ULONG pass1ClearFlag;
    05011     LONG i;
    05012     KIRQL irql;
    05013
    05014     ExAcquireSpinLock( &IopDatabaseLock, &irql );
    05015
    05016     if (Query) {
    05017         pass1SetFlag = DOE_REMOVE_PROCESSED;
    05018         pass1ClearFlag = 0;
    05019     } else {
    05020         pass1SetFlag = DOE_REMOVE_PENDING;
    05021         pass1ClearFlag = DOE_REMOVE_PROCESSED;
    05022     }
    05023
    05024     for (i = 0; i < (LONG)DeviceObjectCount; i++) {
    05025         deviceObject = PhysicalDeviceObjects[i];
    05026         deviceExtension = deviceObject->DeviceObjectExtension;
    05027
    05028         deviceNode = (PDEVICE_NODE)deviceExtension->DeviceNode;
    05029
    05030         ASSERT( deviceNode != NULL );
    05031
    05032         //
    05033         // Assume that at least one device object has a reference.  Walk the
    05034         // entire chain marking them with DOE_REMOVE_PENDING.
    05035         //
    05036
    05037         //
    05038         // We don't actually care how many aggregate references there actually
    05039         // are.  All we're interested in is whether there are any.  So we'll OR
    05040         // them together rather than adding them.  That way we don't have to do
    05041         // testing or branching and we don't have to worry about overflow in the
    05042         // highly unlikely event that there are a total of more references than
    05043         // will fit in a ULONG.
    05044         //
    05045
    05046         referenced = 0;
    05047         attachedDeviceObject = deviceObject;
    05048         do {
    05049             deviceExtension = attachedDeviceObject->DeviceObjectExtension;
    05050
    05051             ASSERT(deviceExtension != NULL);
    05052             ASSERT(!(deviceExtension->ExtensionFlags & pass1SetFlag));
    05053
    05054
    05055             deviceExtension->ExtensionFlags &= ~pass1ClearFlag;
    05056             deviceExtension->ExtensionFlags |= pass1SetFlag;
    05057             referenced |= attachedDeviceObject->ReferenceCount;
    05058
    05059             attachedDeviceObject = attachedDeviceObject->AttachedDevice;
    05060
    05061         } while (attachedDeviceObject != NULL);
    05062
    05063         if (!Query && referenced == 0) {
    05064
    05065             //
    05066             // There aren't any outstanding references, retraverse the chain and
    05067             // mark them all DOE_REMOVE_PROCESSED.  This will still prevent any
    05068             // opens or attaches from occuring but we won't call
    05069             // IopChainDereferenceComplete in IopCompleteUnloadOrDelete.
    05070             //
    05071
    05072             attachedDeviceObject = deviceObject;
    05073             do {
    05074                 deviceExtension = attachedDeviceObject->DeviceObjectExtension;
    05075
    05076                 deviceExtension->ExtensionFlags &= ~DOE_REMOVE_PENDING;
    05077                 deviceExtension->ExtensionFlags |= DOE_REMOVE_PROCESSED;
    05078
    05079                 attachedDeviceObject = attachedDeviceObject->AttachedDevice;
    05080
    05081             } while (attachedDeviceObject != NULL);
    05082
    05083             ExReleaseSpinLock( &IopDatabaseLock, irql );
    05084
    05085             IopChainDereferenceComplete( deviceObject );
    05086
    05087             ExAcquireSpinLock( &IopDatabaseLock, &irql );
    05088         } else if (Query && referenced != 0) {
    05089             break;
    05090         }
    05091     }
    05092
    05093     if (Query && referenced != 0) {
    05094
    05095         if (VetoingDevice != NULL) {
    05096             *VetoingDevice = deviceObject;
    05097         }
    05098
    05099         for (; i >= 0; i--) {
    05100             deviceObject = PhysicalDeviceObjects[i];
    05101             deviceExtension = deviceObject->DeviceObjectExtension;
    05102
    05103             //
    05104             // There are outstanding references, retraverse the chain and
    05105             // unset DOE_REMOVE_PROCESSED.
    05106             //
    05107
    05108             attachedDeviceObject = deviceObject;
    05109             do {
    05110                 deviceExtension = attachedDeviceObject->DeviceObjectExtension;
    05111
    05112                 deviceExtension->ExtensionFlags &= ~DOE_REMOVE_PROCESSED;
    05113
    05114                 attachedDeviceObject = attachedDeviceObject->AttachedDevice;
    05115
    05116             } while (attachedDeviceObject != NULL);
    05117         }
    05118     }
    05119
    05120     ExReleaseSpinLock( &IopDatabaseLock, irql );
    05121
    05122     return !Query || referenced != 0;
    05123 }

NTSTATUS IopOpenLinkOrRenameTarget | ( | OUT PHANDLE | TargetHandle,
|  | IN PIRP | Irp,
|  | IN PVOID | RenameBuffer,
|  | IN PFILE_OBJECT | FileObject
| ) |

Definition at line 5126 of file internal.c.

References ASSERT, CreateFileTypeNone, FileName, FO_OPENED_CASE_SENSITIVE, IO_FORCE_ACCESS_CHECK, IO_NO_PARAMETER_CHECKING, IO_OPEN_TARGET_DIRECTORY, IoCreateFile(), IoFileObjectType, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), Irp, L, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, _IO_STACK_LOCATION::Parameters, UserMode, and USHORT.

Referenced by IoSetInformation(), and NtSetInformationFile().

    05135                    :
    05136
    05137     This routine is invoked by the rename, set link and set copy-on-write code
    05138     in the I/O system's NtSetInformationFile system service when the caller has
    05139     specified a fully qualified file name as the target of a rename, set link,
    05140     or set copy-on-write operation.  This routine attempts to open the parent
    05141     of the specified file and checks the following:
    05142
    05143         o   If the file itself exists, then the caller must have specified that
    05144             the target is to be replaced, otherwise an error is returned.
    05145
    05146         o   Ensures that the target file specification refers to the same volume
    05147             upon which the source file exists.
    05148
    05149 Arguments:
    05150
    05151     TargetHandle - Supplies the address of a variable to return the handle to
    05152         the opened target file if no errors have occurred.
    05153
    05154     Irp - Supplies a pointer to the IRP that represents the current rename
    05155         request.
    05156
    05157     RenameBuffer - Supplies a pointer to the system intermediate buffer that
    05158         contains the caller's rename parameters.
    05159
    05160     FileObject - Supplies a pointer to the file object representing the file
    05161         being renamed.
    05162
    05163 Return Value:
    05164
    05165     The function value is the final status of the operation.
    05166
    05167 Note:
    05168
    05169     This function assumes that the layout of a rename, set link and set
    05170     copy-on-write information structure are exactly the same.
    05171
    05172 --*/
    05173
    05174 {
    05175     NTSTATUS status;
    05176     IO_STATUS_BLOCK ioStatus;
    05177     HANDLE handle;
    05178     OBJECT_ATTRIBUTES objectAttributes;
    05179     UNICODE_STRING newFileName;
    05180     PIO_STACK_LOCATION irpSp;
    05181     PFILE_OBJECT targetFileObject;
    05182     OBJECT_HANDLE_INFORMATION handleInformation;
    05183     PFILE_RENAME_INFORMATION renameBuffer = RenameBuffer;
    05184
    05185     PAGED_CODE();
    05186
    05187     ASSERT( sizeof( FILE_RENAME_INFORMATION ) ==
    05188             sizeof( FILE_LINK_INFORMATION ) );
    05189     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, ReplaceIfExists ) ==
    05190             FIELD_OFFSET( FILE_LINK_INFORMATION, ReplaceIfExists ) );
    05191     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, RootDirectory ) ==
    05192             FIELD_OFFSET( FILE_LINK_INFORMATION, RootDirectory ) );
    05193     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, FileNameLength ) ==
    05194             FIELD_OFFSET( FILE_LINK_INFORMATION, FileNameLength ) );
    05195     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, FileName ) ==
    05196             FIELD_OFFSET( FILE_LINK_INFORMATION, FileName ) );
    05197
    05198     ASSERT( sizeof( FILE_RENAME_INFORMATION ) ==
    05199             sizeof( FILE_MOVE_CLUSTER_INFORMATION ) );
    05200     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, ReplaceIfExists ) ==
    05201             FIELD_OFFSET( FILE_MOVE_CLUSTER_INFORMATION, ClusterCount ) );
    05202     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, RootDirectory ) ==
    05203             FIELD_OFFSET( FILE_MOVE_CLUSTER_INFORMATION, RootDirectory ) );
    05204     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, FileNameLength ) ==
    05205             FIELD_OFFSET( FILE_MOVE_CLUSTER_INFORMATION, FileNameLength ) );
    05206     ASSERT( FIELD_OFFSET( FILE_RENAME_INFORMATION, FileName ) ==
    05207             FIELD_OFFSET( FILE_MOVE_CLUSTER_INFORMATION, FileName ) );
    05208
    05209     //
    05210     // A fully qualified file name was specified.  Begin by attempting to open
    05211     // the parent directory of the specified target file.
    05212     //
    05213
    05214     newFileName.Length = (USHORT) renameBuffer->FileNameLength;
    05215     newFileName.MaximumLength = (USHORT) renameBuffer->FileNameLength;
    05216     newFileName.Buffer = renameBuffer->FileName;
    05217
    05218     InitializeObjectAttributes( &objectAttributes,
    05219                                 &newFileName,
    05220                                 FileObject->Flags & FO_OPENED_CASE_SENSITIVE ? 0 : OBJ_CASE_INSENSITIVE,
    05221                                 renameBuffer->RootDirectory,
    05222                                 (PSECURITY_DESCRIPTOR) NULL );
    05223
    05224     status = IoCreateFile( &handle,
    05225                            FILE_WRITE_DATA | SYNCHRONIZE,
    05226                            &objectAttributes,
    05227                            &ioStatus,
    05228                            (PLARGE_INTEGER) NULL,
    05229                            0,
    05230                            FILE_SHARE_READ | FILE_SHARE_WRITE,
    05231                            FILE_OPEN,
    05232                            FILE_OPEN_FOR_BACKUP_INTENT,
    05233                            (PVOID) NULL,
    05234                            0L,
    05235                            CreateFileTypeNone,
    05236                            (PVOID) NULL,
    05237                            IO_NO_PARAMETER_CHECKING |
    05238                            IO_OPEN_TARGET_DIRECTORY |
    05239                            IO_FORCE_ACCESS_CHECK );
    05240     if (NT_SUCCESS( status )) {
    05241         //
    05242         // The open operation for the target file's parent directory was
    05243         // successful.  Check to see whether or not the file exists.
    05244         //
    05245
    05246         irpSp = IoGetNextIrpStackLocation( Irp );
    05247         if (irpSp->Parameters.SetFile.FileInformationClass == FileLinkInformation &&
    05248             !renameBuffer->ReplaceIfExists &&
    05249             ioStatus.Information == FILE_EXISTS) {
    05250
    05251             //
    05252             // The target file exists, and the caller does not want to replace
    05253             // it.  This is a name collision error so cleanup and return.
    05254             //
    05255
    05256             NtClose( handle );
    05257             status = STATUS_OBJECT_NAME_COLLISION;
    05258
    05259         } else {
    05260
    05261             //
    05262             // Everything up to this point is fine, so dereference the handle
    05263             // to a pointer to the file object and ensure that the two file
    05264             // specifications refer to the same device.
    05265             //
    05266
    05267             status = ObReferenceObjectByHandle( handle,
    05268                                               FILE_WRITE_DATA,
    05269                                               IoFileObjectType,
    05270                                               UserMode,
    05271                                               (PVOID *) &targetFileObject,
    05272                                               &handleInformation );
    05273             if (NT_SUCCESS( status )) {
    05274
    05275                 ObDereferenceObject( targetFileObject );
    05276
    05277                 if (IoGetRelatedDeviceObject( targetFileObject) !=
    05278                     IoGetRelatedDeviceObject( FileObject )) {
    05279
    05280                     //
    05281                     // The two files refer to different devices.  Clean everything
    05282                     // up and return an appropriate error.
    05283                     //
    05284
    05285                     NtClose( handle );
    05286                     status = STATUS_NOT_SAME_DEVICE;
    05287
    05288                 } else {
    05289
    05290                     //
    05291                     // Otherwise, everything worked, so allow the rename operation
    05292                     // to continue.
    05293                     //
    05294
    05295                     irpSp->Parameters.SetFile.FileObject = targetFileObject;
    05296                     *TargetHandle = handle;
    05297                     status = STATUS_SUCCESS;
    05298
    05299                 }
    05300
    05301             } else {
    05302
    05303                 //
    05304                 // There was an error referencing the handle to what should
    05305                 // have been the target directory.  This generally means that
    05306                 // there was a resource problem or the handle was invalid, etc.
    05307                 // Simply attempt to close the handle and return the error.
    05308                 //
    05309
    05310                 NtClose( handle );
    05311
    05312             }
    05313
    05314         }
    05315     }
    05316
    05317     //
    05318     // Return the final status of the operation.
    05319     //
    05320
    05321     return status;
    05322 }

NTSTATUS IopOpenRegistryKey | ( | OUT PHANDLE | Handle,
|  | IN HANDLE BaseHandle | OPTIONAL,
|  | IN PUNICODE_STRING | KeyName,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN BOOLEAN | Create
| ) |

Definition at line 5325 of file internal.c.

References Create(), Handle, KeyName, NULL, and PAGED_CODE.

Referenced by IopAddRemoteBootValuesToRegistry(), IopApplyFunctionToServiceInstances(), IopApplyFunctionToSubKeys(), IopBootLog(), IopCleanupDeviceRegistryValues(), IopCopyBootLogRegistryToFile(), IopCreateMadeupNode(), IopDeleteLegacyKey(), IopDeviceObjectFromDeviceInstance(), IopDeviceObjectToDeviceInstance(), IopDriverLoadingFailed(), IopGetDeviceResourcesFromRegistry(), IopGetGroupOrderIndex(), IopInitializeResourceMap(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopLoadUnloadDriver(), IopOpenCurrentHwProfileDeviceInstanceKey(), IopOpenServiceEnumKeys(), IopPrepareDriverLoading(), IopReadDumpRegistry(), IopSafebootDriverLoad(), IopServiceInstanceToDeviceInstance(), IopSetupRemoteBootCard(), IopUpdateHardwareProfile(), IopWriteResourceList(), IoQueryDeviceDescription(), IoReportHalResourceUsage(), NtUnloadDriver(), pIoQueryBusDescription(), and pIoQueryDeviceDescription().

    05335                    :
    05336
    05337     Opens or creates a VOLATILE registry key using the name passed in based
    05338     at the BaseHandle node.
    05339
    05340 Arguments:
    05341
    05342     Handle - Pointer to the handle which will contain the registry key that
    05343         was opened.
    05344
    05345     BaseHandle - Handle to the base path from which the key must be opened.
    05346
    05347     KeyName - Name of the Key that must be opened/created.
    05348
    05349     DesiredAccess - Specifies the desired access that the caller needs to
    05350         the key.
    05351
    05352     Create - Determines if the key is to be created if it does not exist.
    05353
    05354 Return Value:
    05355
    05356    The function value is the final status of the operation.
    05357
    05358 --*/
    05359
    05360 {
    05361     OBJECT_ATTRIBUTES objectAttributes;
    05362     ULONG disposition;
    05363
    05364     PAGED_CODE();
    05365
    05366     //
    05367     // Initialize the object for the key.
    05368     //
    05369
    05370     InitializeObjectAttributes( &objectAttributes,
    05371                                 KeyName,
    05372                                 OBJ_CASE_INSENSITIVE,
    05373                                 BaseHandle,
    05374                                 (PSECURITY_DESCRIPTOR) NULL );
    05375
    05376     //
    05377     // Create the key or open it, as appropriate based on the caller's
    05378     // wishes.
    05379     //
    05380
    05381     if (Create) {
    05382         return ZwCreateKey( Handle,
    05383                             DesiredAccess,
    05384                             &objectAttributes,
    05385                             0,
    05386                             (PUNICODE_STRING) NULL,
    05387                             REG_OPTION_VOLATILE,
    05388                             &disposition );
    05389     } else {
    05390         return ZwOpenKey( Handle,
    05391                           DesiredAccess,
    05392                           &objectAttributes );
    05393     }
    05394 }

NTSTATUS IopParseDevice | ( | IN PVOID | ParseObject,
|  | IN PVOID | ObjectType,
|  | IN PACCESS_STATE | AccessState,
|  | IN KPROCESSOR_MODE | AccessMode,
|  | IN ULONG | Attributes,
|  | IN OUT PUNICODE_STRING | CompleteName,
|  | IN OUT PUNICODE_STRING | RemainingName,
|  | IN OUT PVOID Context | OPTIONAL,
|  | IN PSECURITY_QUALITY_OF_SERVICE SecurityQos | OPTIONAL,
|  | OUT PVOID * | Object
| ) |

Definition at line 202 of file parse.c.

References _IO_SECURITY_CONTEXT::AccessState, _OPEN_PACKET::AllocationSize, APC_LEVEL, ASSERT, _IRP::AssociatedIrp, _DEVICE_OBJECT::AttachedDevice, _OPEN_PACKET::BasicInformation, _OBJECT_HEADER::Body, _IRP::Cancel, _IRP::CancelRoutine, _DEVICE_OBJECT::Characteristics, _IO_STACK_LOCATION::Control, COPY_ATTRIBUTES, _OPEN_PACKET::CreateFileType, CreateFileTypeNamedPipe, CreateFileTypeNone, _OPEN_PACKET::CreateOptions, _IRP::CurrentLocation, _OPEN_PACKET::DeleteOnly, _IO_SECURITY_CONTEXT::DesiredAccess, _FILE_OBJECT::DeviceObject, _VPB::DeviceObject, _IO_STACK_LOCATION::DeviceObject, _DEVICE_OBJECT::DeviceType, _OPEN_PACKET::Disposition, _DEVICE_OBJECT::DriverObject, _OPEN_PACKET::EaBuffer, _OPEN_PACKET::EaLength, _FILE_OBJECT::Event, ExAcquireResourceShared, ExAllocatePool, ExAllocatePoolWithTag, EXCEPTION_EXECUTE_HANDLER, Executive, ExFreePool(), ExInterlockedAddUlong(), ExReleaseResource, _OPEN_PACKET::ExtraCreateParameters, FALSE, _DRIVER_OBJECT::FastIoDispatch, _FAST_IO_DISPATCH::FastIoQueryBasicInfo, _FAST_IO_DISPATCH::FastIoQueryNetworkOpenInfo, _FAST_IO_DISPATCH::FastIoQueryOpen, FILE_OBJECT, _OPEN_PACKET::FileAttributes, _FILE_OBJECT::FileName, _IO_STACK_LOCATION::FileObject, _OPEN_PACKET::FileObject, _OPEN_PACKET::FinalStatus, _FILE_OBJECT::Flags, _IRP::Flags, _IO_STACK_LOCATION::Flags, FO_ALERTABLE_IO, FO_DIRECT_DEVICE_OPEN, FO_FILE_OPEN_CANCELLED, FO_NO_INTERMEDIATE_BUFFERING, FO_OPENED_CASE_SENSITIVE, FO_RANDOM_ACCESS, FO_SEQUENTIAL_ONLY, FO_SYNCHRONOUS_IO, FO_VOLUME_OPEN, FO_WRITE_THROUGH, _OPEN_PACKET::FullAttributes, _IO_SECURITY_CONTEXT::FullCreateOptions, _OBJECT_TYPE_INITIALIZER::GenericMapping, _KEVENT::Header, _OPEN_PACKET::Information, IO_FORCE_ACCESS_CHECK, IO_MAX_REMOUNT_REPARSE_ATTEMPTS, IO_REMOUNT, IO_REPARSE, IO_TYPE_FILE, IO_TYPE_OPEN_PACKET, IoCallDriver, IoFileObjectType, IoFreeIrp(), IoGetAttachedDevice(), IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAllocateIrp, IopCheckBackupRestorePrivilege(), IopCheckDeviceAndDriver(), IopCheckVpbMounted(), IopDecrementDeviceObjectRef(), IopDeleteFile(), IopDequeueThreadIrp, IopDereferenceVpbAndFree(), IopDoNameTransmogrify(), IopQueueThreadIrp, IopSecurityResource, IopVpbSpinLock, IoQueryFileInformation(), IoSetNextIrpStackLocation, _IRP::IoStatus, IRP_BUFFERED_IO, IRP_CREATE_OPERATION, IRP_DEALLOCATE_BUFFER, IRP_DEFER_IO_COMPLETION, IRP_MJ_CREATE, IRP_MJ_CREATE_MAILSLOT, IRP_MJ_CREATE_NAMED_PIPE, IRP_SYNCHRONOUS_API, KeEnterCriticalRegion, KeInitializeEvent, KeLeaveCriticalRegion, KeLowerIrql(), KeRaiseIrql(), KernelMode, KeWaitForSingleObject(), KPROCESSOR_MODE, L, _OPEN_PACKET::LocalFileObject, _IO_STACK_LOCATION::MajorFunction, _IRP::MdlAddress, _OPEN_PACKET::NetworkInformation, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObCreateObject(), ObDereferenceObject, _DUMMY_FILE_OBJECT::ObjectHeader, ObReferenceObject, OPEN_PACKET_PATTERN, _OPEN_PACKET::Options, _IRP::Overlay, _OPEN_PACKET::Override, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, _OPEN_PACKET::ParseCheck, PDRIVER_CANCEL, _IRP::PendingReturned, PKNORMAL_ROUTINE, _OBJECT_HEADER::PointerCount, PsGetCurrentThread, _OPEN_PACKET::QueryOnly, _VPB::ReferenceCount, _OPEN_PACKET::RelatedFileObject, _FILE_OBJECT::RelatedFileObject, _IRP::RequestorMode, RoundNameSize, RtlCopyUnicodeString(), RtlMapGenericMask(), SE_BACKUP_PRIVILEGES_CHECKED, SeAccessCheck(), SeAppendPrivileges(), _DEVICE_OBJECT::SecurityDescriptor, _IO_SECURITY_CONTEXT::SecurityQos, SecurityQos, SeFastTraverseCheck(), SeFreePrivileges(), SeLockSubjectContext(), SeOpenObjectAuditAlarm(), SeSetAccessStateGenericMapping(), SeTraverseAuditAlarm(), SeUnlockSubjectContext(), _OPEN_PACKET::ShareAccess, _DISPATCHER_HEADER::SignalState, _OPEN_PACKET::Size, _FILE_OBJECT::Size, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, SL_CASE_SENSITIVE, _IRP::StackCount, _DEVICE_OBJECT::StackSize, _IRP::Tail, TOKEN_HAS_TRAVERSE_PRIVILEGE, TOKEN_IS_RESTRICTED, TRUE, _OPEN_PACKET::Type, _OBJECT_HEADER::Type, _FILE_OBJECT::Type, _OBJECT_TYPE::TypeInfo, _IRP::UserEvent, _IRP::UserIosb, UserMode, VOID(), and _FILE_OBJECT::Vpb.

Referenced by IopCreateObjectTypes(), and IopParseFile().

    00217                    :
    00218
    00219     This routine interfaces to the NT Object Manager.  It is invoked when
    00220     the object system is given the name of an entity to create or open and the
    00221     name translates to a device object.  This routine is specified as the parse
    00222     routine for all device objects.
    00223
    00224     In the normal case of an NtCreateFile, the user specifies either the name
    00225     of a device or of a file.  In the former situation, this routine is invoked
    00226     with a pointer to the device and a null ("") string.  For this case, the
    00227     routine simply allocates an IRP, fills it in, and passes it to the driver
    00228     for the device.  The driver will then perform whatever rudimentary functions
    00229     are necessary and will return a status code indicating whether an error was
    00230     incurred.  This status code is remembered in the Open Packet (OP).
    00231
    00232     In the latter situation, the name string to be opened/created is non-null.
    00233     That is, it contains the remainder of the pathname to the file that is to
    00234     be opened or created.  For this case, the routine allocates an IRP, fills
    00235     it in, and passes it to the driver for the device.  The driver may then
    00236     need to take further action or it may complete the request immediately.  If
    00237     it needs to perform some work asynchronously, then it can queue the request
    00238     and return a status of STATUS_PENDING.  This allows this routine and its
    00239     caller to return to the user so that he can continue.  Otherwise, the open/
    00240     create is basically finished.
    00241
    00242     If the driver supports symbolic links, then it is also possible for the
    00243     driver to return a new name.  This name will be returned to the Object
    00244     Manager as a new name to look up.  The parsing will then begin again from
    00245     the start.
    00246
    00247     It is also the responsibility of this routine to create a file object for
    00248     the file, if the name specifies a file.  The file object's address is
    00249     returned to the NtCreateFile service through the OP.
    00250
    00251 Arguments:
    00252
    00253     ParseObject - Pointer to the device object the name translated into.
    00254
    00255     ObjectType - Type of the object being opened.
    00256
    00257     AccessState - Running security access state information for operation.
    00258
    00259     AccessMode - Access mode of the original caller.
    00260
    00261     Attributes - Attributes to be applied to the object.
    00262
    00263     CompleteName - Complete name of the object.
    00264
    00265     RemainingName - Remaining name of the object.
    00266
    00267     Context - Pointer to an Open Packet (OP) from NtCreateFile service.
    00268
    00269     SecurityQos - Optional security quality of service indicator.
    00270
    00271     Object - The address of a variable to receive the created file object, if
    00272         any.
    00273
    00274 Return Value:
    00275
    00276     The function return value is one of the following:
    00277
    00278         a)  Success - This indicates that the function succeeded and the object
    00279             parameter contains the address of the created file object.
    00280
    00281         b)  Error - This indicates that the file was not found or created and
    00282             no file object was created.
    00283
    00284         c)  Reparse - This indicates that the remaining name string has been
    00285             replaced by a new name that is to be parsed.
    00286
    00287 --*/
    00288
    00289 {
    00290
    00291 #define COPY_ATTRIBUTES( n, b, s ) {                                    \
    00292         (n)->CreationTime.QuadPart = (b)->CreationTime.QuadPart;        \
    00293         (n)->LastAccessTime.QuadPart = (b)->LastAccessTime.QuadPart;    \
    00294         (n)->LastWriteTime.QuadPart = (b)->LastWriteTime.QuadPart;      \
    00295         (n)->ChangeTime.QuadPart = (b)->ChangeTime.QuadPart;            \
    00296         (n)->AllocationSize.QuadPart = (s)->AllocationSize.QuadPart;    \
    00297         (n)->EndOfFile.QuadPart = (s)->EndOfFile.QuadPart;              \
    00298         (n)->FileAttributes = (b)->FileAttributes; }
    00299
    00300     PIRP irp;
    00301     PIO_STACK_LOCATION irpSp;
    00302     POPEN_PACKET op;
    00303     PFILE_OBJECT fileObject;
    00304     NTSTATUS status;
    00305     IO_STATUS_BLOCK ioStatus;
    00306     IO_SECURITY_CONTEXT securityContext;
    00307     PDEVICE_OBJECT deviceObject;
    00308     PDEVICE_OBJECT parseDeviceObject;
    00309     BOOLEAN directDeviceOpen;
    00310     PVPB vpb;
    00311     ACCESS_MASK desiredAccess;
    00312     PDUMMY_FILE_OBJECT localFileObject;
    00313     BOOLEAN realFileObjectRequired;
    00314     KPROCESSOR_MODE modeForPrivilegeCheck;
    00315     ULONG retryCount = 0;
    00316     BOOLEAN  relativeVolumeOpen = FALSE;     // True if opening a filesystem volume
    00317
    00318     PAGED_CODE();
    00319
    00320 reparse_loop:
    00321
    00322     //
    00323     // Assume failure by setting the returned object pointer to NULL.
    00324     //
    00325
    00326     *Object = (PVOID) NULL;
    00327
    00328     //
    00329     // Get the address of the Open Packet (OP).
    00330     //
    00331
    00332     op = Context;
    00333
    00334     //
    00335     // Ensure that this routine is actually being invoked because someone is
    00336     // attempting to open a device or a file through NtCreateFile.  This code
    00337     // must be invoked from there (as opposed to some other random object
    00338     // create or open routine).
    00339     //
    00340
    00341     if (op == NULL ||
    00342         op->Type != IO_TYPE_OPEN_PACKET ||
    00343         op->Size != sizeof( OPEN_PACKET )) {
    00344
    00345         return STATUS_OBJECT_TYPE_MISMATCH;
    00346     }
    00347
    00348     //
    00349     // Obtain a pointer to the parse object as a device object, which is the
    00350     // actual type of the object anyway.
    00351     //
    00352
    00353     parseDeviceObject = (PDEVICE_OBJECT) ParseObject;
    00354
    00355     //
    00356     // If this is a relative open, then get the device on which the file
    00357     // is really being opened from the related file object and use that for
    00358     // the remainder of this function and for all operations performed on
    00359     // the file object that is about to be created.
    00360     //
    00361
    00362     if (op->RelatedFileObject) {
    00363         parseDeviceObject = op->RelatedFileObject->DeviceObject;
    00364     }
    00365
    00366     //
    00367     // Make sure that the device and its driver are really there and they are
    00368     // going to stay there.  The object itself cannot go away just yet because
    00369     // the object management system has performed a reference which bumps the
    00370     // count of the number of reasons why the object must stick around.
    00371     // However, the driver could be attempting to unload itself, so perform
    00372     // this check.  If the driver is being unloaded, then set the final status
    00373     // of the operation to "No such device" and return with a NULL file object
    00374     // pointer.
    00375     //
    00376     // Note that it is possible to "open" an exclusive device more than once
    00377     // provided that the caller is performing a relative open.  This feature
    00378     // is how users "allocate" a device, and then use it to perform operations.
    00379     //
    00380
    00381     status = IopCheckDeviceAndDriver( op, parseDeviceObject );
    00382
    00383     if (!NT_SUCCESS(status)) {
    00384         return op->FinalStatus = status;
    00385     }
    00386
    00387     //
    00388     // Since ObOpenObjectByName is called without being passed
    00389     // any object type information, we need to map the generic
    00390     // bits in the DesiredAccess mask here.  We also need to save
    00391     // the object's generic mapping in the access state structure
    00392     // here, because this is the earliest opportunity we have
    00393     // to do so.
    00394     //
    00395
    00396     RtlMapGenericMask( &AccessState->RemainingDesiredAccess,
    00397                        &IoFileObjectType->TypeInfo.GenericMapping );
    00398
    00399     RtlMapGenericMask( &AccessState->OriginalDesiredAccess,
    00400                        &IoFileObjectType->TypeInfo.GenericMapping );
    00401
    00402     SeSetAccessStateGenericMapping( AccessState, &IoFileObjectType->TypeInfo.GenericMapping );
    00403
    00404     desiredAccess = AccessState->RemainingDesiredAccess;
    00405
    00406     //
    00407     // Compute the previous mode to be passed in to the privilege check
    00408     //
    00409
    00410     if (AccessMode != KernelMode || op->Options & IO_FORCE_ACCESS_CHECK) {
    00411         modeForPrivilegeCheck = UserMode;
    00412     } else {
    00413         modeForPrivilegeCheck = KernelMode;
    00414     }
    00415
    00416     IopCheckBackupRestorePrivilege( AccessState,
    00417                                     &op->CreateOptions,
    00418                                     modeForPrivilegeCheck,
    00419                                     op->Disposition
    00420                                     );
    00421
    00422     //
    00423     // If this is not the first time through here for this object, and the
    00424     // object itself is being opened, then the desired access must also
    00425     // include the previously granted access from the last pass.  Likewise,
    00426     // if the privileges have been checked already, then this is another
    00427     // pass through for a file, so add in the previously granted access.
    00428     //
    00429
    00430     if ((op->Override && !RemainingName->Length) ||
    00431         AccessState->Flags & SE_BACKUP_PRIVILEGES_CHECKED) {
    00432         desiredAccess |= AccessState->PreviouslyGrantedAccess;
    00433     }
    00434
    00435     //
    00436     // If its a filesystem volume open and we are doing a relative open to it
    00437     // then do the access check. Note that relative opens can be nested and we propagate
    00438     // the fact that the relative open is for a volume using the FO_VOLUME_OPEN flag.
    00439     //
    00440
    00441     if (op->RelatedFileObject) {
    00442         if ((op->RelatedFileObject->Flags & FO_VOLUME_OPEN) && RemainingName->Length == 0) {
    00443             relativeVolumeOpen = TRUE;
    00444         }
    00445     }
    00446
    00447     //
    00448     // Now determine what type of security check should be made.  This is
    00449     // based on whether the remaining name string is null.  If it is null,
    00450     // then the device itself is being opened, so a full security check is
    00451     // performed.  Otherwise, only a check to ensure that the caller can
    00452     // traverse the device object is made.  Note that these checks are only
    00453     // made if the caller's mode is user, or if access checking is being
    00454     // forced.  Note also that if an access check was already made on the
    00455     // device itself, and this code is being executed again because of a
    00456     // reparse, then the access check need not be made the second time
    00457     // around.
    00458     //
    00459
    00460
    00461     if ((AccessMode != KernelMode || op->Options & IO_FORCE_ACCESS_CHECK) &&
    00462         (!op->RelatedFileObject || relativeVolumeOpen) &&
    00463         !op->Override) {
    00464
    00465         BOOLEAN subjectContextLocked = FALSE;
    00466         BOOLEAN accessGranted;
    00467         ACCESS_MASK grantedAccess;
    00468
    00469         //
    00470         // The caller's mode is either user or access checking is being
    00471         // forced.  Perform the appropriate access check on the device
    00472         // object.
    00473         //
    00474
    00475         if (!RemainingName->Length) {
    00476
    00477             UNICODE_STRING nameString;
    00478             PPRIVILEGE_SET privileges = NULL;
    00479
    00480             //
    00481             // The device itself is being opened.  Make a full security check
    00482             // to ensure that the caller has the appropriate access.
    00483             //
    00484
    00485             KeEnterCriticalRegion( );
    00486             ExAcquireResourceShared( &IopSecurityResource, TRUE );
    00487
    00488             SeLockSubjectContext( &AccessState->SubjectSecurityContext );
    00489             subjectContextLocked = TRUE;
    00490
    00491             accessGranted = SeAccessCheck( parseDeviceObject->SecurityDescriptor,
    00492                                            &AccessState->SubjectSecurityContext,
    00493                                            subjectContextLocked,
    00494                                            desiredAccess,
    00495                                            0,
    00496                                            &privileges,
    00497                                            &IoFileObjectType->TypeInfo.GenericMapping,
    00498                                            UserMode,
    00499                                            &grantedAccess,
    00500                                            &status );
    00501
    00502             if (privileges) {
    00503                 (VOID) SeAppendPrivileges( AccessState,
    00504                                            privileges );
    00505                 SeFreePrivileges( privileges );
    00506             }
    00507
    00508             if (accessGranted) {
    00509                 AccessState->PreviouslyGrantedAccess |= grantedAccess;
    00510                 AccessState->RemainingDesiredAccess &= ~( grantedAccess | MAXIMUM_ALLOWED );
    00511                 op->Override = TRUE;
    00512             }
    00513
    00514             nameString.Length = 8;
    00515             nameString.MaximumLength = 8;
    00516             nameString.Buffer = L"File";
    00517
    00518             SeOpenObjectAuditAlarm( &nameString,
    00519                                     parseDeviceObject,
    00520                                     CompleteName,
    00521                                     parseDeviceObject->SecurityDescriptor,
    00522                                     AccessState,
    00523                                     FALSE,
    00524                                     accessGranted,
    00525                                     UserMode,
    00526                                     &AccessState->GenerateOnClose );
    00527
    00528             ExReleaseResource( &IopSecurityResource );
    00529             KeLeaveCriticalRegion();
    00530
    00531         } else {
    00532
    00533             //
    00534             // The device is not being opened, rather, a file on the device
    00535             // is being opened or created.  Therefore, only perform a check
    00536             // here for traverse access to the device.
    00537             //
    00538
    00539             //
    00540             // First determine if we have to perform traverse checking at all.
    00541             // Traverse checking only needs to be done if the device being
    00542             // traversed is a disk, or if the caller does not already have
    00543             // traverse checking privilege.  Note that the former case is so
    00544             // that an administrator can turn off access to the "system
    00545             // partition", or someone would be able to install a trojan horse
    00546             // into the system by simply replacing one of the files there with
    00547             // something of their own.
    00548             //
    00549
    00550             if (!(AccessState->Flags & TOKEN_HAS_TRAVERSE_PRIVILEGE) ||
    00551                 parseDeviceObject->DeviceType == FILE_DEVICE_DISK ||
    00552                 parseDeviceObject->DeviceType == FILE_DEVICE_CD_ROM ) {
    00553
    00554                 KeEnterCriticalRegion( );
    00555                 ExAcquireResourceShared( &IopSecurityResource, TRUE );
    00556
    00557                 //
    00558                 // If the token is restricted we need to do the full
    00559                 // access check.
    00560                 //
    00561
    00562                 if ((AccessState->Flags & TOKEN_IS_RESTRICTED) == 0) {
    00563                     accessGranted = SeFastTraverseCheck( parseDeviceObject->SecurityDescriptor,
    00564                                                          FILE_TRAVERSE,
    00565                                                          UserMode );
    00566                 } else {
    00567                     accessGranted = FALSE;
    00568                 }
    00569
    00570                 if (!accessGranted) {
    00571
    00572                     PPRIVILEGE_SET privileges = NULL;
    00573
    00574                     //
    00575                     // The caller was not granted traverse access through the
    00576                     // normal fast path lookup.  Perform a full-blown access
    00577                     // check to determine whether some other ACE allows traverse
    00578                     // access.
    00579                     //
    00580
    00581                     SeLockSubjectContext( &AccessState->SubjectSecurityContext );
    00582
    00583                     subjectContextLocked = TRUE;
    00584
    00585                     accessGranted = SeAccessCheck( parseDeviceObject->SecurityDescriptor,
    00586                                                    &AccessState->SubjectSecurityContext,
    00587                                                    subjectContextLocked,
    00588                                                    FILE_TRAVERSE,
    00589                                                    0,
    00590                                                    &privileges,
    00591                                                    &IoFileObjectType->TypeInfo.GenericMapping,
    00592                                                    UserMode,
    00593                                                    &grantedAccess,
    00594                                                    &status );
    00595
    00596                     if (privileges) {
    00597
    00598                         (VOID) SeAppendPrivileges( AccessState,
    00599                                                    privileges );
    00600                         SeFreePrivileges( privileges );
    00601                     }
    00602
    00603                 }
    00604
    00605                 //
    00606                 // Perform the traverse audit alarm if necessary.
    00607                 //
    00608
    00609                 SeTraverseAuditAlarm( &AccessState->OperationID,
    00610                                       parseDeviceObject,
    00611                                       parseDeviceObject->SecurityDescriptor,
    00612                                       &AccessState->SubjectSecurityContext,
    00613                                       subjectContextLocked,
    00614                                       FILE_TRAVERSE,
    00615                                       (PPRIVILEGE_SET) NULL,
    00616                                       accessGranted,
    00617                                       UserMode );
    00618                 ExReleaseResource( &IopSecurityResource );
    00619                 KeLeaveCriticalRegion();
    00620
    00621             } else {
    00622
    00623                     accessGranted = TRUE;
    00624             }
    00625         }
    00626
    00627         //
    00628         // Unlock the subject's security context so that it can be changed,
    00629         // if it was locked.
    00630         //
    00631
    00632         if (subjectContextLocked) {
    00633             SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
    00634         }
    00635
    00636         //
    00637         // Finally, determine whether or not access was granted to the device.
    00638         // If not, clean everything up and get out now without even invoking
    00639         // the device driver.
    00640         //
    00641
    00642         if (!accessGranted) {
    00643
    00644             IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    00645             return STATUS_ACCESS_DENIED;
    00646         }
    00647
    00648     }
    00649
    00650     realFileObjectRequired = !(op->QueryOnly || op->DeleteOnly);
    00651
    00652     if (RemainingName->Length == 0 &&
    00653         op->RelatedFileObject == NULL &&
    00654         ((desiredAccess & ~(SYNCHRONIZE |
    00655                             FILE_READ_ATTRIBUTES |
    00656                             READ_CONTROL |
    00657                             ACCESS_SYSTEM_SECURITY |
    00658                             WRITE_OWNER |
    00659                             WRITE_DAC)) == 0) &&
    00660         realFileObjectRequired) {
    00661
    00662         //
    00663         // If the name of the object being opened is just the name of the
    00664         // device itself, and there is no related file object, and the caller
    00665         // is opening the device for only read attributes access, then this
    00666         // device will not be mounted.  This allows applications to obtain
    00667         // attributes about the device without actually mounting it.
    00668         //
    00669         // Note that if this *is* a direct device open, then the normal path
    00670         // through the I/O system and drivers may never be used, even if
    00671         // the device appears to be mounted.  This is because the user may
    00672         // remove the media from the drive (even though it is mounted), and
    00673         // now attempting to determine what type of drive it is will still
    00674         // fail, this time very hard, because a whole mount process is now
    00675         // required, thus defeating this feature.
    00676         //
    00677
    00678         directDeviceOpen = TRUE;
    00679
    00680     } else {
    00681
    00682         //
    00683         // Otherwise, this is a normal open of a file, directory, device, or
    00684         // volume.
    00685         //
    00686
    00687         directDeviceOpen = FALSE;
    00688     }
    00689
    00690     //
    00691     // There are now five different cases.  These are as follows:
    00692     //
    00693     //    1)  This is a relative open, in which case we want to send the
    00694     //        request to then same device that opened the relative file object.
    00695     //
    00696     //    2)  The VPB pointer in the device object is NULL.  This means that
    00697     //        this device does not support a file system.  This includes
    00698     //        devices such as terminals, etc.
    00699     //
    00700     //    3)  The VPB pointer in the device object is not NULL and:
    00701     //
    00702     //        a)  The VPB is "blank".  That is, the VPB has never been filled
    00703     //            in, which means that the device has never been mounted.
    00704     //
    00705     //        b)  The VPB is non-blank, but the verify flag on the device is
    00706     //            set, indicating that the door to the drive may have been
    00707     //            opened and the media may therefore have been changed.
    00708     //
    00709     //        c)  The VPB is non-blank and the verify flag is not set.
    00710     //
    00711     //        Both of the latter are not explicitly checked for, as #c is
    00712     //        the normal case, and #b is the responsibility of the file
    00713     //        system to check.
    00714     //
    00715
    00716     //
    00717     //  If this is a file system that supports volumes, vpbRefCount will
    00718     //  be filled in to point to the reference count in the Vpb.  Error
    00719     //  exits paths later on key off this value to see if they should
    00720     //  decrement the ref count.  Note that a direct device open does not
    00721     //  make it to the file system, so no increment is needed, and no
    00722     //  decrement will be performed in objsup.c IopDeleteFile().
    00723     //
    00724
    00725     vpb = NULL;
    00726
    00727     //
    00728     // If the related open was a direct device open then we should go through the full mount
    00729     // path for this open as this may not be a direct device open.
    00730     //
    00731     if (op->RelatedFileObject && (!(op->RelatedFileObject->Flags & FO_DIRECT_DEVICE_OPEN))) {
    00732
    00733         deviceObject = (PDEVICE_OBJECT)ParseObject;
    00734
    00735         if (op->RelatedFileObject->Vpb) {
    00736
    00737             vpb = op->RelatedFileObject->Vpb;
    00738
    00739             //
    00740             // Synchronize here with the file system to make sure that
    00741             // volumes don't go away while en route to the FS.
    00742             //
    00743
    00744             ExInterlockedAddUlong( &vpb->ReferenceCount, 1, &IopVpbSpinLock );
    00745         }
    00746
    00747     } else {
    00748
    00749         deviceObject = parseDeviceObject;
    00750
    00751         if (parseDeviceObject->Vpb && !directDeviceOpen) {
    00752             vpb = IopCheckVpbMounted( op,
    00753                                       parseDeviceObject,
    00754                                       RemainingName,
    00755                                       &status );
    00756             if ( !vpb ) {
    00757                 return status;
    00758             }
    00759
    00760             //
    00761             // Set the address of the device object associated with the VPB.
    00762             //
    00763
    00764             deviceObject = vpb->DeviceObject;
    00765         }
    00766
    00767         //
    00768         // Walk the attached device list.
    00769         //
    00770
    00771         if (deviceObject->AttachedDevice) {
    00772             deviceObject = IoGetAttachedDevice( deviceObject );
    00773         }
    00774     }
    00775
    00776     //
    00777     //  If the driver says that the IO manager should do the access checks, lets do it here.
    00778     //  We do the check against the parse device object as that device object has a name
    00779     //  and we can set an ACL against it.
    00780     //  We only worry about related opens of devices as the other case is taken care of in the
    00781     //  filesystem.
    00782     //
    00783     if ((deviceObject->Characteristics & FILE_DEVICE_SECURE_OPEN) &&
    00784         (op->RelatedFileObject || RemainingName->Length) &&  (!relativeVolumeOpen)) {
    00785
    00786         BOOLEAN subjectContextLocked = FALSE;
    00787         BOOLEAN accessGranted;
    00788         ACCESS_MASK grantedAccess;
    00789         UNICODE_STRING nameString;
    00790         PPRIVILEGE_SET privileges = NULL;
    00791
    00792         //
    00793         // If the device wants to ensure secure opens then lets check the two
    00794         // cases which were skipped earlier. These cases are if its a relative
    00795         // open or if there are trailing names.
    00796         //
    00797
    00798         KeEnterCriticalRegion( );
    00799         ExAcquireResourceShared( &IopSecurityResource, TRUE );
    00800
    00801         SeLockSubjectContext( &AccessState->SubjectSecurityContext );
    00802         subjectContextLocked = TRUE;
    00803
    00804         accessGranted = SeAccessCheck( parseDeviceObject->SecurityDescriptor,
    00805                                        &AccessState->SubjectSecurityContext,
    00806                                        subjectContextLocked,
    00807                                        desiredAccess,
    00808                                        0,
    00809                                        &privileges,
    00810                                        &IoFileObjectType->TypeInfo.GenericMapping,
    00811                                        UserMode,
    00812                                        &grantedAccess,
    00813                                        &status );
    00814
    00815         if (privileges) {
    00816             (VOID) SeAppendPrivileges( AccessState,
    00817                                        privileges );
    00818             SeFreePrivileges( privileges );
    00819         }
    00820
    00821         if (accessGranted) {
    00822             AccessState->PreviouslyGrantedAccess |= grantedAccess;
    00823             AccessState->RemainingDesiredAccess &= ~( grantedAccess | MAXIMUM_ALLOWED );
    00824         }
    00825
    00826         nameString.Length = 8;
    00827         nameString.MaximumLength = 8;
    00828         nameString.Buffer = L"File";
    00829
    00830         SeOpenObjectAuditAlarm( &nameString,
    00831                                 deviceObject,
    00832                                 CompleteName,
    00833                                 parseDeviceObject->SecurityDescriptor,
    00834                                 AccessState,
    00835                                 FALSE,
    00836                                 accessGranted,
    00837                                 UserMode,
    00838                                 &AccessState->GenerateOnClose );
    00839
    00840         SeUnlockSubjectContext( &AccessState->SubjectSecurityContext );
    00841         ExReleaseResource( &IopSecurityResource );
    00842         KeLeaveCriticalRegion();
    00843
    00844         if (!accessGranted) {
    00845             IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    00846
    00847             if (vpb) {
    00848                 IopDereferenceVpbAndFree(vpb);
    00849             }
    00850             return STATUS_ACCESS_DENIED;
    00851         }
    00852     }
    00853
    00854     //
    00855     // Allocate and fill in the I/O Request Packet (IRP) to use in interfacing
    00856     // to the driver.  The allocation is done using an exception handler in
    00857     // case the caller does not have enough quota to allocate the packet.
    00858     //
    00859
    00860     irp = IopAllocateIrp( deviceObject->StackSize, TRUE );
    00861     if (!irp) {
    00862
    00863         //
    00864         // An IRP could not be allocated.  Cleanup and return an appropriate
    00865         // error status code.
    00866         //
    00867
    00868         IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    00869
    00870         if (vpb) {
    00871             IopDereferenceVpbAndFree(vpb);
    00872         }
    00873         return STATUS_INSUFFICIENT_RESOURCES;
    00874     }
    00875     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    00876     irp->RequestorMode = AccessMode;
    00877     irp->Flags = IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API | IRP_DEFER_IO_COMPLETION;
    00878
    00879     securityContext.SecurityQos = SecurityQos;
    00880     securityContext.AccessState = AccessState;
    00881     securityContext.DesiredAccess = desiredAccess;
    00882     securityContext.FullCreateOptions = op->CreateOptions;
    00883
    00884     //
    00885     // Get a pointer to the stack location for the first driver.  This is where
    00886     // the original function codes and parameters are passed.
    00887     //
    00888
    00889     irpSp = IoGetNextIrpStackLocation( irp );
    00890     irpSp->Control = 0;
    00891
    00892     if (op->CreateFileType == CreateFileTypeNone) {
    00893
    00894         //
    00895         // This is a normal file open or create function.
    00896         //
    00897
    00898         irpSp->MajorFunction = IRP_MJ_CREATE;
    00899         irpSp->Parameters.Create.EaLength = op->EaLength;
    00900         irpSp->Flags = (UCHAR) op->Options;
    00901         if (!(Attributes & OBJ_CASE_INSENSITIVE)) {
    00902             irpSp->Flags |= SL_CASE_SENSITIVE;
    00903         }
    00904
    00905     } else if (op->CreateFileType == CreateFileTypeNamedPipe) {
    00906
    00907         //
    00908         // A named pipe is being created.
    00909         //
    00910
    00911         irpSp->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
    00912         irpSp->Parameters.CreatePipe.Parameters = op->ExtraCreateParameters;
    00913
    00914     } else {
    00915
    00916         //
    00917         // A mailslot is being created.
    00918         //
    00919
    00920         irpSp->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
    00921         irpSp->Parameters.CreateMailslot.Parameters = op->ExtraCreateParameters;
    00922     }
    00923
    00924     //
    00925     // Also fill in the NtCreateFile service's caller's parameters.
    00926     //
    00927
    00928     irp->Overlay.AllocationSize = op->AllocationSize;
    00929     irp->AssociatedIrp.SystemBuffer = op->EaBuffer;
    00930     irpSp->Parameters.Create.Options = (op->Disposition << 24) | (op->CreateOptions & 0x00ffffff);
    00931     irpSp->Parameters.Create.FileAttributes = op->FileAttributes;
    00932     irpSp->Parameters.Create.ShareAccess = op->ShareAccess;
    00933     irpSp->Parameters.Create.SecurityContext = &securityContext;
    00934
    00935     //
    00936     // Fill in local parameters so this routine can determine when the I/O is
    00937     // finished, and the normal I/O completion code will not get any errors.
    00938     //
    00939
    00940     irp->UserIosb = &ioStatus;
    00941     irp->MdlAddress = (PMDL) NULL;
    00942     irp->PendingReturned = FALSE;
    00943     irp->Cancel = FALSE;
    00944     irp->UserEvent = (PKEVENT) NULL;
    00945     irp->CancelRoutine = (PDRIVER_CANCEL) NULL;
    00946     irp->Tail.Overlay.AuxiliaryBuffer = (PVOID) NULL;
    00947
    00948     //
    00949     // Allocate and initialize the file object that will be used in dealing
    00950     // with the device for the remainder of this session with the user.  How
    00951     // the file object is allocated is based on whether or not a real file
    00952     // object is actually required.  It is not required for the query and
    00953     // delete only operations.
    00954     //
    00955
    00956     if (realFileObjectRequired) {
    00957
    00958         OBJECT_ATTRIBUTES objectAttributes;
    00959
    00960         //
    00961         // A real, full-blown file object is actually required.
    00962         //
    00963
    00964         InitializeObjectAttributes( &objectAttributes,
    00965                                     (PUNICODE_STRING) NULL,
    00966                                     Attributes,
    00967                                     (HANDLE) NULL,
    00968                                     (PSECURITY_DESCRIPTOR) NULL
    00969                                   );
    00970
    00971         status = ObCreateObject( KernelMode,
    00972                                  IoFileObjectType,
    00973                                  &objectAttributes,
    00974                                  AccessMode,
    00975                                  (PVOID) NULL,
    00976                                  (ULONG) sizeof( FILE_OBJECT ),
    00977                                  0,
    00978                                  0,
    00979                                  (PVOID *) &fileObject );
    00980
    00981         if (!NT_SUCCESS( status )) {
    00982             IoFreeIrp( irp );
    00983
    00984             IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    00985
    00986             if (vpb) {
    00987                IopDereferenceVpbAndFree(vpb);
    00988             }
    00989             return op->FinalStatus = status;
    00990         }
    00991
    00992         RtlZeroMemory( fileObject, sizeof( FILE_OBJECT ) );
    00993         fileObject->Type = IO_TYPE_FILE;
    00994         fileObject->Size = sizeof( FILE_OBJECT );
    00995         fileObject->RelatedFileObject = op->RelatedFileObject;
    00996         if (op->CreateOptions & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) {
    00997             fileObject->Flags = FO_SYNCHRONOUS_IO;
    00998             if (op->CreateOptions & FILE_SYNCHRONOUS_IO_ALERT) {
    00999                 fileObject->Flags |= FO_ALERTABLE_IO;
    01000             }
    01001         }
    01002
    01003         //
    01004         // Now fill in the file object as best is possible at this point and set
    01005         // a pointer to it in the IRP so everyone else can find it.
    01006         //
    01007
    01008         if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    01009             KeInitializeEvent( &fileObject->Lock, SynchronizationEvent, FALSE );
    01010             fileObject->Waiters = 0;
    01011             fileObject->CurrentByteOffset.QuadPart = 0;
    01012         }
    01013         if (op->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) {
    01014             fileObject->Flags |= FO_NO_INTERMEDIATE_BUFFERING;
    01015         }
    01016         if (op->CreateOptions & FILE_WRITE_THROUGH) {
    01017             fileObject->Flags |= FO_WRITE_THROUGH;
    01018         }
    01019         if (op->CreateOptions & FILE_SEQUENTIAL_ONLY) {
    01020             fileObject->Flags |= FO_SEQUENTIAL_ONLY;
    01021         }
    01022         if (op->CreateOptions & FILE_RANDOM_ACCESS) {
    01023             fileObject->Flags |= FO_RANDOM_ACCESS;
    01024         }
    01025
    01026     } else {
    01027
    01028         //
    01029         // This is either a quick delete or query operation.  For these cases,
    01030         // it is possible to optimize the Object Manager out of the picture by
    01031         // simply putting together something that "looks" like a file object,
    01032         // and then operating on it.
    01033         //
    01034
    01035         localFileObject = op->LocalFileObject;
    01036         RtlZeroMemory( localFileObject, sizeof( DUMMY_FILE_OBJECT ) );
    01037         fileObject = (PFILE_OBJECT) &localFileObject->ObjectHeader.Body;
    01038         localFileObject->ObjectHeader.Type = IoFileObjectType;
    01039         localFileObject->ObjectHeader.PointerCount = 1;
    01040     }
    01041
    01042     if (directDeviceOpen) {
    01043         fileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
    01044     }
    01045     if (!(Attributes & OBJ_CASE_INSENSITIVE)) {
    01046         fileObject->Flags |= FO_OPENED_CASE_SENSITIVE;
    01047     }
    01048
    01049     fileObject->Type = IO_TYPE_FILE;
    01050     fileObject->Size = sizeof( FILE_OBJECT );
    01051     fileObject->RelatedFileObject = op->RelatedFileObject;
    01052     fileObject->DeviceObject = parseDeviceObject;
    01053
    01054     irp->Tail.Overlay.OriginalFileObject = fileObject;
    01055     irpSp->FileObject = fileObject;
    01056
    01057     //
    01058     // Allocate a file name string buffer which is large enough to contain
    01059     // the entire remaining name string and initialize the maximum length.
    01060     //
    01061
    01062     if (RemainingName->Length) {
    01063         fileObject->FileName.MaximumLength = RoundNameSize( RemainingName->Length );
    01064         fileObject->FileName.Buffer = ExAllocatePoolWithTag( PagedPool,
    01065                                                              fileObject->FileName.MaximumLength,
    01066                                                              'mNoI' );
    01067         if (!fileObject->FileName.Buffer) {
    01068             IoFreeIrp( irp );
    01069
    01070             IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    01071
    01072             if (vpb) {
    01073                IopDereferenceVpbAndFree(vpb);
    01074             }
    01075             fileObject->DeviceObject = (PDEVICE_OBJECT) NULL;
    01076             if (realFileObjectRequired) {
    01077                 ObDereferenceObject( fileObject );
    01078             }
    01079             return STATUS_INSUFFICIENT_RESOURCES;
    01080         }
    01081     }
    01082
    01083     //
    01084     // Now copy the name string into the file object from the remaining name
    01085     // that is being reparsed.  If the driver decides to reparse, then it must
    01086     // replace this name.
    01087     //
    01088
    01089     RtlCopyUnicodeString( &fileObject->FileName, RemainingName );
    01090
    01091     //
    01092     // Before invoking the driver's open routine, check to see whether or not
    01093     // this is a fast network attributes query and, if so, and the driver
    01094     // implements the function, attempt to call it here.
    01095     //
    01096
    01097     if (op->QueryOnly) {
    01098         PFAST_IO_DISPATCH fastIoDispatch = deviceObject->DriverObject->FastIoDispatch;
    01099         BOOLEAN result;
    01100
    01101         if (fastIoDispatch &&
    01102             fastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET( FAST_IO_DISPATCH, FastIoQueryOpen ) &&
    01103             fastIoDispatch->FastIoQueryOpen) {
    01104
    01105             IoSetNextIrpStackLocation( irp );
    01106             irpSp->DeviceObject = deviceObject;
    01107             result = (fastIoDispatch->FastIoQueryOpen)( irp,
    01108                                                         op->NetworkInformation,
    01109                                                         deviceObject );
    01110             if (result) {
    01111                 op->FinalStatus = irp->IoStatus.Status;
    01112                 op->Information = irp->IoStatus.Information;
    01113
    01114                 //
    01115                 // The operation worked, so simply dereference and free the
    01116                 // resources acquired up to this point.
    01117                 //
    01118
    01119                 if ((op->FinalStatus == STATUS_REPARSE) &&
    01120                     irp->Tail.Overlay.AuxiliaryBuffer) {
    01121                     ASSERT( op->Information > IO_REPARSE_TAG_RESERVED_ONE );
    01122                     ExFreePool( irp->Tail.Overlay.AuxiliaryBuffer );
    01123                     irp->Tail.Overlay.AuxiliaryBuffer = NULL;
    01124                     op->RelatedFileObject = (PFILE_OBJECT) NULL;
    01125                 }
    01126
    01127                 if (fileObject->FileName.Length) {
    01128                     ExFreePool( fileObject->FileName.Buffer );
    01129                 }
    01130
    01131                 IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    01132
    01133                 if (vpb) {
    01134                     IopDereferenceVpbAndFree(vpb);
    01135                 }
    01136
    01137 #if DBG
    01138                 irp->CurrentLocation = irp->StackCount + 2;
    01139 #endif // DBG
    01140
    01141                 IoFreeIrp( irp );
    01142
    01143                 //
    01144                 // Finally, indicate that the parse routine was actually
    01145                 // invoked and that the information returned herein can be
    01146                 // used.
    01147                 //
    01148
    01149                 op->ParseCheck = OPEN_PACKET_PATTERN;
    01150                 status = STATUS_SUCCESS;
    01151
    01152                 if (!op->FullAttributes) {
    01153                     try {
    01154                         op->BasicInformation->FileAttributes = op->NetworkInformation->FileAttributes;
    01155                     } except(EXCEPTION_EXECUTE_HANDLER) {
    01156                         status = GetExceptionCode();
    01157                     }
    01158                 }
    01159
    01160                 return status;
    01161
    01162             } else {
    01163
    01164                 //
    01165                 // The fast I/O operation did not work, so take the longer
    01166                 // route.
    01167                 //
    01168
    01169                 irp->Tail.Overlay.CurrentStackLocation++;
    01170                 irp->CurrentLocation++;
    01171             }
    01172         }
    01173     }
    01174
    01175     //
    01176     // Finally, initialize the file object's event to the Not Signaled state
    01177     // and remember that a file object was created.
    01178     //
    01179
    01180     KeInitializeEvent( &fileObject->Event, NotificationEvent, FALSE );
    01181     op->FileObject = fileObject;
    01182
    01183     //
    01184     // Insert the packet at the head of the IRP list for the thread.
    01185     //
    01186
    01187     IopQueueThreadIrp( irp );
    01188
    01189     //
    01190     // Now invoke the driver itself to open the file.
    01191     //
    01192
    01193     status = IoCallDriver( deviceObject, irp );
    01194
    01195     //
    01196     // One of four things may have happened when the driver was invoked:
    01197     //
    01198     //    1.  The I/O operation is pending (Status == STATUS_PENDING).  This can
    01199     //        occur on devices which need to perform some sort of device
    01200     //        manipulation (such as opening a file for a file system).
    01201     //
    01202     //    2.  The driver returned an error (Status < 0). This occurs when either
    01203     //        a supplied parameter was in error, or the device or file system
    01204     //        incurred or discovered an error.
    01205     //
    01206     //    3.  The operation ended in a reparse (Status == STATUS_REPARSE).  This
    01207     //        occurs when a file system opens the file, only to discover that it
    01208     //        represents a symbolic link.
    01209     //
    01210     //    4.  The operation is complete and was successful (Status ==
    01211     //        STATUS_SUCCESS).  Note that for this case the only action is to
    01212     //        return a pointer to the file object.
    01213     //
    01214
    01215     if (status == STATUS_PENDING) {
    01216
    01217         (VOID) KeWaitForSingleObject( &fileObject->Event,
    01218                                       Executive,
    01219                                       KernelMode,
    01220                                       FALSE,
    01221                                       (PLARGE_INTEGER) NULL );
    01222         status = ioStatus.Status;
    01223
    01224     } else {
    01225
    01226         //
    01227         // The I/O operation was completed without returning a status of
    01228         // pending.  This means that at this point, the IRP has not been
    01229         // fully completed.  Complete it now.
    01230         //
    01231
    01232         PKNORMAL_ROUTINE normalRoutine;
    01233         PVOID normalContext;
    01234         KIRQL irql;
    01235
    01236         ASSERT( !irp->PendingReturned );
    01237         ASSERT( !irp->MdlAddress );
    01238
    01239         //
    01240         // In the case of name junctions do the transmogrify work.
    01241         //
    01242
    01243         if (irp->IoStatus.Status == STATUS_REPARSE &&
    01244             irp->IoStatus.Information == IO_REPARSE_TAG_MOUNT_POINT ) {
    01245
    01246             PREPARSE_DATA_BUFFER reparseBuffer = NULL;
    01247
    01248             ASSERT ( irp->Tail.Overlay.AuxiliaryBuffer != NULL );
    01249
    01250             reparseBuffer = (PREPARSE_DATA_BUFFER) irp->Tail.Overlay.AuxiliaryBuffer;
    01251
    01252             ASSERT( reparseBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT );
    01253             ASSERT( reparseBuffer->ReparseDataLength < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
    01254             ASSERT( reparseBuffer->Reserved < MAXIMUM_REPARSE_DATA_BUFFER_SIZE );
    01255
    01256             IopDoNameTransmogrify( irp,
    01257                                    fileObject,
    01258                                    reparseBuffer );
    01259         }
    01260
    01261         //
    01262         // Now finish up the request.
    01263         //
    01264
    01265         KeRaiseIrql( APC_LEVEL, &irql );
    01266
    01267         //
    01268         // Note that normally the system would simply call IopCompleteRequest
    01269         // here to complete the packet.  However, because this is a create
    01270         // operation, several assumptions can be made that make it much faster
    01271         // to perform the couple of operations that completing the request
    01272         // would perform.  These include:  copying the I/O status block,
    01273         // dequeueing the IRP and freeing it, and setting the file object's
    01274         // event to the signalled state.  The latter is done here by hand,
    01275         // since it is known that it is not possible for any thread to be
    01276         // waiting on the event.
    01277         //
    01278
    01279         ioStatus = irp->IoStatus;
    01280         status = ioStatus.Status;
    01281
    01282         fileObject->Event.Header.SignalState = 1;
    01283
    01284         IopDequeueThreadIrp( irp );
    01285
    01286         //
    01287         // The SystemBuffer is in some cases used by the driver, and
    01288         // needs to be freed if present.
    01289         //
    01290
    01291         if ((irp->Flags & IRP_BUFFERED_IO) && (irp->Flags & IRP_DEALLOCATE_BUFFER)) {
    01292             ExFreePool(irp->AssociatedIrp.SystemBuffer);
    01293         }
    01294
    01295         IoFreeIrp( irp );
    01296
    01297         KeLowerIrql( irql );
    01298     }
    01299
    01300     //
    01301     // Copy the information field of the I/O status block back to the
    01302     // original caller in case it is required.
    01303     //
    01304
    01305     op->Information = ioStatus.Information;
    01306
    01307     if (!NT_SUCCESS( status )) {
    01308         int openCancelled;
    01309
    01310         //
    01311         // The operation ended in an error.  Kill the file object, dereference
    01312         // the device object, and return a null pointer.
    01313         //
    01314
    01315         if (fileObject->FileName.Length) {
    01316             ExFreePool( fileObject->FileName.Buffer );
    01317             fileObject->FileName.Length = 0;
    01318         }
    01319
    01320         fileObject->DeviceObject = (PDEVICE_OBJECT) NULL;
    01321
    01322         openCancelled = (fileObject->Flags & FO_FILE_OPEN_CANCELLED);
    01323
    01324         if (realFileObjectRequired) {
    01325             ObDereferenceObject( fileObject );
    01326         }
    01327         op->FileObject = (PFILE_OBJECT) NULL;
    01328
    01329         IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    01330
    01331         if ((!openCancelled) && (vpb )) {
    01332             IopDereferenceVpbAndFree(vpb);
    01333         }
    01334
    01335         return op->FinalStatus = status;
    01336
    01337     } else if (status == STATUS_REPARSE) {
    01338
    01339         //
    01340         // The operation resulted in a reparse.  This means that the file
    01341         // name in the file object is the new name to be looked up. Replace
    01342         // the complete name string with the new name and return STATUS_REPARSE
    01343         // so the object manager knows to start over again.  Note, however,
    01344         // that the file name buffer in the file object itself is kept intact
    01345         // so that it can be reused when coming back here again.
    01346         //
    01347         // A reparse status may also have been returned from the file system if
    01348         // the volume that was in a drive needed to have been verified, but
    01349         // the verification failed, and a new volume was mounted.  In this
    01350         // case, everything starts over again using the new volume.
    01351         //
    01352
    01353         ASSERT( IO_REPARSE == IO_REPARSE_TAG_RESERVED_ZERO );
    01354
    01355         if ((ioStatus.Information == IO_REPARSE) ||
    01356             (ioStatus.Information == IO_REPARSE_TAG_MOUNT_POINT)) {
    01357
    01358             //
    01359             // If the complete name buffer isn't large enough, reallocate it.
    01360             //
    01361
    01362             if (CompleteName->MaximumLength < fileObject->FileName.Length) {
    01363
    01364                 PVOID buffer;
    01365
    01366                 buffer = ExAllocatePoolWithTag( PagedPool,
    01367                                                 fileObject->FileName.Length,
    01368                                                 'cFoI' );
    01369                 if (!buffer) {
    01370                     return op->FinalStatus = STATUS_INSUFFICIENT_RESOURCES;
    01371                 } else {
    01372                     if (CompleteName->Buffer) {
    01373                         ExFreePool( CompleteName->Buffer );
    01374                     }
    01375                     CompleteName->Buffer = buffer;
    01376                     CompleteName->MaximumLength = fileObject->FileName.Length;
    01377                 }
    01378             }
    01379
    01380             RtlCopyUnicodeString( CompleteName, &fileObject->FileName );
    01381
    01382             //
    01383             // For NTFS directory junction points we NULL the RelatedFileObject.
    01384             // If the prior call was a relative open, the subsequent one will
    01385             // not be.
    01386             //
    01387
    01388             if (ioStatus.Information == IO_REPARSE_TAG_MOUNT_POINT) {
    01389
    01390                 op->RelatedFileObject = (PFILE_OBJECT) NULL;
    01391             }
    01392         }
    01393
    01394         //
    01395         // Kill the file object, dereference the device object, and return a
    01396         // null pointer.
    01397         //
    01398
    01399         if (fileObject->FileName.Length) {
    01400             ExFreePool( fileObject->FileName.Buffer );
    01401             fileObject->FileName.Length = 0;
    01402         }
    01403
    01404         fileObject->DeviceObject = (PDEVICE_OBJECT) NULL;
    01405
    01406         if (realFileObjectRequired) {
    01407             ObDereferenceObject( fileObject );
    01408         }
    01409         op->FileObject = (PFILE_OBJECT) NULL;
    01410
    01411         IopDecrementDeviceObjectRef( parseDeviceObject, FALSE );
    01412
    01413         if (vpb) {
    01414             IopDereferenceVpbAndFree(vpb);
    01415         }
    01416
    01417         ASSERT( IO_REMOUNT == IO_REPARSE_TAG_RESERVED_ONE );
    01418
    01419         if (ioStatus.Information == IO_REPARSE_TAG_RESERVED_ONE) {
    01420
    01421             //
    01422             // If we are reparsing to verify a volume, restart the reparse
    01423             // by attempting to parse the device once again.  Note that it
    01424             // would be best to simply recurse, but it's not possible since
    01425             // there is a limited amount of stack available to kernel mode
    01426             // and a limit needs to be enforced for the number of times that
    01427             // verify reparse can occur.
    01428             //
    01429
    01430             if (++retryCount > IO_MAX_REMOUNT_REPARSE_ATTEMPTS) {
    01431
    01432                 return STATUS_UNSUCCESSFUL;
    01433             }
    01434             goto reparse_loop;
    01435
    01436         } else {
    01437
    01438             //
    01439             // Really reparsing a symbolic link, so go back to the object
    01440             // manager so it can begin the parse from the top.
    01441             //
    01442
    01443             op->RelatedFileObject = (PFILE_OBJECT) NULL;
    01444             return STATUS_REPARSE;
    01445         }
    01446
    01447     } else {
    01448
    01449         //
    01450         // The operation was successful. The first thing to do is to see if
    01451         // the device that processed the open also opened the file. If
    01452         // not, we need to adjust the vpb reference counts. Then, if this is
    01453         // not a query or a delete, but rather a normal open/create, return
    01454         // the address of the FileObject to the caller and set the
    01455         // information returned in the original requestor's I/O status block.
    01456         // Also set the value of the parse check field in the open packet to
    01457         // a value which will let the caller know that this routine was
    01458         // successful in creating the file object. Finally, return the status
    01459         // of the operation to the caller.
    01460         //
    01461
    01462         PDEVICE_OBJECT deviceObjectThatOpenedFile;
    01463
    01464         deviceObjectThatOpenedFile = IoGetRelatedDeviceObject(fileObject);
    01465         if (deviceObject != deviceObjectThatOpenedFile) {
    01466             //
    01467             // The device that opened the related file is not the one
    01468             // that opened this file. So, readjust the vpb reference
    01469             // counts.
    01470             if (vpb) {
    01471                 IopDereferenceVpbAndFree(vpb);
    01472             }
    01473             vpb = fileObject->Vpb;
    01474             if (vpb) {
    01475                 ExInterlockedAddUlong(
    01476                     &vpb->ReferenceCount, 1, &IopVpbSpinLock );
    01477             }
    01478         }
    01479
    01480         if (realFileObjectRequired) {
    01481
    01482             *Object = fileObject;
    01483             op->ParseCheck = OPEN_PACKET_PATTERN;
    01484
    01485             //
    01486             // Add a reference so the file object cannot go away before
    01487             // the create routine gets chance to flag the object for handle
    01488             // create.
    01489             //
    01490
    01491             ObReferenceObject( fileObject );
    01492
    01493             //
    01494             // If the filename length is zero and its not a relative open or
    01495             // its a relative open to a volume open then set the volume open flag.
    01496             // Also set it only for filesystem device object volume.
    01497             //
    01498             if ((!fileObject->RelatedFileObject || fileObject->RelatedFileObject->Flags & FO_VOLUME_OPEN) &&
    01499                 (!fileObject->FileName.Length)) {
    01500                 switch (deviceObjectThatOpenedFile->DeviceType) {
    01501                 case FILE_DEVICE_DISK_FILE_SYSTEM:
    01502                 case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
    01503                 case FILE_DEVICE_TAPE_FILE_SYSTEM:
    01504                 case FILE_DEVICE_FILE_SYSTEM:
    01505
    01506                     fileObject->Flags |= FO_VOLUME_OPEN;
    01507                     break;
    01508
    01509                 default:
    01510                     break;
    01511                 }
    01512             }
    01513
    01514             return op->FinalStatus = ioStatus.Status;
    01515
    01516         } else {
    01517
    01518             //
    01519             // This is either a quick query or delete operation.  Determine
    01520             // which it is and quickly perform the operation.
    01521             //
    01522
    01523             if (op->QueryOnly) {
    01524                 PFAST_IO_DISPATCH fastIoDispatch;
    01525                 BOOLEAN queryResult = FALSE;
    01526
    01527                 fastIoDispatch = deviceObjectThatOpenedFile->DriverObject->FastIoDispatch;
    01528
    01529                 if (!op->FullAttributes) {
    01530                     PFILE_BASIC_INFORMATION basicInfo = NULL;
    01531
    01532                     //
    01533                     // This is a simple FAT file attribute query.  Attempt to
    01534                     // obtain the basic information about the file.
    01535                     //
    01536
    01537                     try {
    01538
    01539                         if (fastIoDispatch && fastIoDispatch->FastIoQueryBasicInfo) {
    01540                             queryResult = fastIoDispatch->FastIoQueryBasicInfo(
    01541                                             fileObject,
    01542                                             TRUE,
    01543                                             op->BasicInformation,
    01544                                             &ioStatus,
    01545                                             deviceObjectThatOpenedFile
    01546                                             );
    01547                         }
    01548                         if (!queryResult) {
    01549                             ULONG returnedLength;
    01550
    01551                             basicInfo = ExAllocatePool( NonPagedPool,
    01552                                                         sizeof( FILE_BASIC_INFORMATION ) );
    01553                             if (basicInfo) {
    01554                                 status = IoQueryFileInformation(
    01555                                             fileObject,
    01556                                             FileBasicInformation,
    01557                                             sizeof( FILE_BASIC_INFORMATION ),
    01558                                             basicInfo,
    01559                                             &returnedLength
    01560                                             );
    01561                                 if (NT_SUCCESS( status )) {
    01562                                     RtlCopyMemory( op->BasicInformation,
    01563                                                    basicInfo,
    01564                                                    returnedLength );
    01565                                 }
    01566                                 ExFreePool( basicInfo );
    01567                             } else {
    01568                                 status = STATUS_INSUFFICIENT_RESOURCES;
    01569                             }
    01570                         } else {
    01571                             status = ioStatus.Status;
    01572                         }
    01573                     } except(EXCEPTION_EXECUTE_HANDLER) {
    01574                         if (basicInfo) {
    01575                             ExFreePool( basicInfo );
    01576                         }
    01577                         status = GetExceptionCode();
    01578                     }
    01579
    01580                 } else {
    01581
    01582                     //
    01583                     // This is a full attribute query.  Attempt to obtain the
    01584                     // full network attributes for the file.  This includes
    01585                     // both the basic and standard information about the
    01586                     // file.  Try the fast path first, if it exists.
    01587                     //
    01588
    01589                     if (fastIoDispatch &&
    01590                         fastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET( FAST_IO_DISPATCH, FastIoQueryNetworkOpenInfo ) &&
    01591                         fastIoDispatch->FastIoQueryNetworkOpenInfo) {
    01592                         queryResult = fastIoDispatch->FastIoQueryNetworkOpenInfo(
    01593                                         fileObject,
    01594                                         TRUE,
    01595                                         op->NetworkInformation,
    01596                                         &ioStatus,
    01597                                         deviceObjectThatOpenedFile
    01598                                         );
    01599                     }
    01600                     if (!queryResult) {
    01601                         ULONG returnedLength;
    01602
    01603                         //
    01604                         // Either the fast dispatch routine did not exist, or
    01605                         // it simply wasn't callable at this time.  Attempt to
    01606                         // obtain all of the information at once via an IRP-
    01607                         // based call.
    01608                         //
    01609
    01610                         status = IoQueryFileInformation(
    01611                                     fileObject,
    01612                                     FileNetworkOpenInformation,
    01613                                     sizeof( FILE_NETWORK_OPEN_INFORMATION ),
    01614                                     op->NetworkInformation,
    01615                                     &returnedLength
    01616                                     );
    01617
    01618                         if (!NT_SUCCESS( status )) {
    01619                             if (status == STATUS_INVALID_PARAMETER ||
    01620                                 status == STATUS_NOT_IMPLEMENTED) {
    01621                                 FILE_BASIC_INFORMATION basicInfo;
    01622                                 FILE_STANDARD_INFORMATION stdInfo;
    01623
    01624                                 //
    01625                                 // The IRP-based call did not work either, so
    01626                                 // simply try to obtain the information by
    01627                                 // doing IRP-based queries for the basic and
    01628                                 // standard information and piecing together
    01629                                 // the results into the caller's buffer.  Note
    01630                                 // that it might be possible to perform fast
    01631                                 // I/O operations to get the data, but it
    01632                                 // might also fail because of the above.  So
    01633                                 // simply query the information the long way.
    01634                                 //
    01635
    01636                                 status = IoQueryFileInformation(
    01637                                             fileObject,
    01638                                             FileBasicInformation,
    01639                                             sizeof( FILE_BASIC_INFORMATION ),
    01640                                             &basicInfo,
    01641                                             &returnedLength
    01642                                             );
    01643                                 if (NT_SUCCESS( status )) {
    01644                                     status = IoQueryFileInformation(
    01645                                                 fileObject,
    01646                                                 FileStandardInformation,
    01647                                                 sizeof( FILE_STANDARD_INFORMATION ),
    01648                                                 &stdInfo,
    01649                                                 &returnedLength
    01650                                                 );
    01651                                     if (NT_SUCCESS( status )) {
    01652                                         COPY_ATTRIBUTES( op->NetworkInformation,
    01653                                                          &basicInfo,
    01654                                                          &stdInfo );
    01655                                     }
    01656                                 }
    01657                             }
    01658                         }
    01659                     }
    01660                 }
    01661
    01662             } else {
    01663
    01664                 //
    01665                 // There is nothing to do for a quick delete since the caller
    01666                 // set the FILE_DELETE_ON_CLOSE CreateOption so it is already
    01667                 // set in the file system.
    01668                 //
    01669
    01670                 NOTHING;
    01671
    01672             }
    01673
    01674             op->ParseCheck = OPEN_PACKET_PATTERN;
    01675             if (realFileObjectRequired) {
    01676                 ObDereferenceObject( fileObject );
    01677             } else {
    01678                 IopDeleteFile( fileObject );
    01679             }
    01680             op->FileObject = (PFILE_OBJECT) NULL;
    01681
    01682             op->FinalStatus = status;
    01683
    01684             return status;
    01685         }
    01686     }
    01687 }

NTSTATUS IopParseFile | ( | IN PVOID | ParseObject,
|  | IN PVOID | ObjectType,
|  | IN PACCESS_STATE | AccessState,
|  | IN KPROCESSOR_MODE | AccessMode,
|  | IN ULONG | Attributes,
|  | IN OUT PUNICODE_STRING | CompleteName,
|  | IN OUT PUNICODE_STRING | RemainingName,
|  | IN OUT PVOID Context | OPTIONAL,
|  | IN PSECURITY_QUALITY_OF_SERVICE SecurityQos | OPTIONAL,
|  | OUT PVOID * | Object
| ) |

Definition at line 1690 of file parse.c.

References IO_TYPE_OPEN_PACKET, IoGetRelatedDeviceObject(), IopParseDevice(), NULL, PAGED_CODE, _OPEN_PACKET::RelatedFileObject, SecurityQos, _OPEN_PACKET::Size, and _OPEN_PACKET::Type.

Referenced by IopCreateObjectTypes().

    01705                    :
    01706
    01707     This routine interfaces to the NT Object Manager.  It is invoked when
    01708     the object system is given the name of an entity to create or open and is
    01709     also given a handle to a directory file object that the operation is to be
    01710     performed relative to.  This routine is specified as the parse routine for
    01711     all file objects.
    01712
    01713     This routine simply invokes the parse routine for the appropriate device
    01714     that is associated with the file object.  It is the responsibility of that
    01715     routine to perform the operation.
    01716
    01717 Arguments:
    01718
    01719     ParseObject - Pointer to the file object that the name is to be opened or
    01720         created relative to.
    01721
    01722     ObjectType - Type of the object being opened.
    01723
    01724     AccessState - Running security access state information for operation.
    01725
    01726     AccessMode - Access mode of the original caller.
    01727
    01728     Attributes - Attributes to be applied to the object.
    01729
    01730     CompleteName - Complete name of the object.
    01731
    01732     RemainingName - Remaining name of the object.
    01733
    01734     Context - Pointer to an Open Packet (OP) from NtCreateFile service.
    01735
    01736     SecurityQos - Supplies a pointer to the captured QOS information
    01737         if available.
    01738
    01739     Object - The address of a variable to receive the created file object, if
    01740         any.
    01741
    01742 Return Value:
    01743
    01744     The function return value is one of the following:
    01745
    01746         a)  Success - This indicates that the function succeeded and the object
    01747             parameter contains the address of the created file object.
    01748
    01749         b)  Error - This indicates that the file was not found or created and
    01750             no file object was created.
    01751
    01752         c)  Reparse - This indicates that the remaining name string has been
    01753             replaced by a new name that is to be parsed.
    01754
    01755 --*/
    01756
    01757 {
    01758     PDEVICE_OBJECT deviceObject;
    01759     POPEN_PACKET op;
    01760
    01761     PAGED_CODE();
    01762
    01763     //
    01764     // Get the address of the Open Packet (OP).
    01765     //
    01766
    01767     op = (POPEN_PACKET) Context;
    01768
    01769     //
    01770     // Ensure that this routine is actually being invoked because someone is
    01771     // attempting to open a device or a file through NtCreateFile.  This code
    01772     // must be invoked from there (as opposed to some other random object
    01773     // create or open routine).
    01774     //
    01775
    01776     if (op == NULL ||
    01777         op->Type != IO_TYPE_OPEN_PACKET ||
    01778         op->Size != sizeof( OPEN_PACKET )) {
    01779         return STATUS_OBJECT_TYPE_MISMATCH;
    01780     }
    01781
    01782     //
    01783     // Get a pointer to the device object for this file.
    01784     //
    01785
    01786     deviceObject = IoGetRelatedDeviceObject( (PFILE_OBJECT) ParseObject );
    01787
    01788     //
    01789     // Pass the related file object to the device object parse routine.
    01790     //
    01791
    01792     op->RelatedFileObject = (PFILE_OBJECT) ParseObject;
    01793
    01794     //
    01795     // Open or create the specified file.
    01796     //
    01797
    01798     return IopParseDevice( deviceObject,
    01799                            ObjectType,
    01800                            AccessState,
    01801                            AccessMode,
    01802                            Attributes,
    01803                            CompleteName,
    01804                            RemainingName,
    01805                            Context,
    01806                            SecurityQos,
    01807                            Object );
    01808 }

BOOLEAN IopProtectSystemPartition | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 53 of file arcsec.c.

References ASSERT, IOP_SYSTEM_PART_PROT_KEY, IOP_SYSTEM_PART_PROT_VALUE, IopApplySystemPartitionProt(), NT_SUCCESS, NtClose(), NtOpenKey(), NtQueryValueKey(), NTSTATUS(), NULL, RtlInitUnicodeString(), and TRUE.

Referenced by IoInitSystem().

    00059                    :
    00060
    00061     This routine assigns protection to the system partition of an
    00062     ARC system, if necessary.  If this is not an ARC system, or
    00063     the system partition does not need to be protected, then this
    00064     routine does nothing.
    00065
    00066
    00067 Arguments:
    00068
    00069     LoaderBlock - Supplies a pointer to the loader parameter block that was
    00070         created by the OS Loader.
    00071
    00072 Return Value:
    00073
    00074     The function value is a BOOLEAN indicating whether or not protection
    00075     has been appropriately applied.   TRUE indicates no errors were
    00076     encountered.  FALSE indicates an error was encountered.
    00077
    00078
    00079 --*/
    00080
    00081 {
    00082
    00083     //
    00084     // We only entertain the possibility of assigning protection
    00085     // to the system partition if we are an ARC system.  For the
    00086     // time being, the best way to determine if you are an ARC
    00087     // system is to see if you aren't and X86 machine.  DavidRo
    00088     // believes that at some point in the future we will have
    00089     // ARC compliant X86 machines.  At that point in time, we
    00090     // will need to change the following #ifdef's into something
    00091     // that does a run-time determination.
    00092     //
    00093
    00094 #ifdef i386  // if (!ARC-Compliant system)
    00095
    00096
    00097     //
    00098     // Nothing to do for non-ARC systems
    00099     //
    00100
    00101     return(TRUE);
    00102
    00103
    00104 #else // ARC-COMPLIANT system
    00105
    00106     NTSTATUS status;
    00107     NTSTATUS tmpStatus;
    00108     HANDLE keyHandle;
    00109     OBJECT_ATTRIBUTES objectAttributes;
    00110     UNICODE_STRING keyName;
    00111     UNICODE_STRING valueName;
    00112     ULONG resultLength;
    00113     ULONG keyBuffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( ULONG )];
    00114     PKEY_VALUE_PARTIAL_INFORMATION keyValue;
    00115
    00116     //
    00117     // This is an ARC system.  Attempt to retrieve information from the registry
    00118     // indicating whether or not we should protect the system partition.
    00119     //
    00120
    00121     RtlInitUnicodeString( &keyName, IOP_SYSTEM_PART_PROT_KEY );
    00122     InitializeObjectAttributes( &objectAttributes,
    00123                                 &keyName,
    00124                                 OBJ_CASE_INSENSITIVE,
    00125                                 NULL,
    00126                                 NULL );
    00127     status = NtOpenKey( &keyHandle, KEY_READ, &objectAttributes);
    00128
    00129     if (NT_SUCCESS( status )) {
    00130
    00131         keyValue = (PKEY_VALUE_PARTIAL_INFORMATION) &keyBuffer[0];
    00132         RtlInitUnicodeString( &valueName, IOP_SYSTEM_PART_PROT_VALUE );
    00133         status = NtQueryValueKey( keyHandle,
    00134                                   &valueName,
    00135                                   KeyValuePartialInformation,
    00136                                   keyValue,
    00137                                   sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( ULONG ),
    00138                                   &resultLength );
    00139
    00140         if (NT_SUCCESS( status )) {
    00141
    00142             PBOOLEAN applyIt;
    00143
    00144             //
    00145             // The appropriate information was located in the registry.  Now
    00146             // determine whether or not is indicates that protection is to be
    00147             // applied.
    00148             //
    00149
    00150             applyIt = &(keyValue->Data[0]);
    00151
    00152             if (*applyIt) {
    00153                 status = IopApplySystemPartitionProt( LoaderBlock );
    00154             }
    00155         }
    00156
    00157         tmpStatus = NtClose( keyHandle );
    00158         ASSERT(NT_SUCCESS( tmpStatus ));
    00159     }
    00160
    00161
    00162     return TRUE;
    00163
    00164 #endif // ARC-COMPLIANT system
    00165 }

NTSTATUS IopQueryDeviceCapabilities | ( | IN PDEVICE_NODE | DeviceNode,
|  | OUT PDEVICE_CAPABILITIES | Capabilities
| ) |

Definition at line 3694 of file pnpenum.c.

    03701                    :
    03702
    03703     This routine will issue an irp to the DeviceObject to retrieve the
    03704     pnp device capabilities.
    03705     Should only be called twice - first from IopProcessNewDeviceNode,
    03706     and second from IopDeviceNodeCapabilitiesToRegistry, called after
    03707     device is started. If you consider calling this device, see if
    03708     DeviceNode->CapabilityFlags does what you need instead (accessed
    03709     via IopDeviceNodeFlagsToCapabilities(...).
    03710
    03711 Arguments:
    03712
    03713     DeviceNode - the device object the request should be sent to.
    03714
    03715     Capabilities - a capabilities structure to be filled in by the driver.
    03716
    03717 Return Value:
    03718
    03719     status
    03720
    03721 --*/
    03722
    03723 {
    03724     IO_STACK_LOCATION irpStack;
    03725     PVOID dummy;
    03726
    03727     NTSTATUS status;
    03728
    03729     //
    03730     // Initialize the capabilities structure.
    03731     //
    03732
    03733     RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
    03734     Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
    03735     Capabilities->Version = 1;
    03736     Capabilities->Address = Capabilities->UINumber = (ULONG)-1;
    03737
    03738     //
    03739     // Initialize the stack location to pass to IopSynchronousCall()
    03740     //
    03741
    03742     RtlZeroMemory(&irpStack, sizeof(IO_STACK_LOCATION));
    03743
    03744     //
    03745     // Query the device's capabilities
    03746     //
    03747
    03748     irpStack.MajorFunction = IRP_MJ_PNP;
    03749     irpStack.MinorFunction = IRP_MN_QUERY_CAPABILITIES;
    03750     irpStack.Parameters.DeviceCapabilities.Capabilities = Capabilities;
    03751
    03752     status = IopSynchronousCall(DeviceNode->PhysicalDeviceObject,
    03753                                 &irpStack,
    03754                                 &dummy);
    03755
    03756     ASSERT(status != STATUS_PENDING);
    03757
    03758     return status;
    03759 }

NTSTATUS IopQueryName | ( | IN PVOID | Object,
|  | IN BOOLEAN | HasObjectName,
|  | OUT POBJECT_NAME_INFORMATION | ObjectNameInfo,
|  | IN ULONG | Length,
|  | OUT PULONG | ReturnLength
| ) |

Definition at line 1811 of file parse.c.

References ASSERT, _FILE_OBJECT::DeviceObject, ExAllocatePoolWithTag, ExFreePool(), FileName, _FILE_OBJECT::Flags, FO_SYNCHRONOUS_IO, IopGetFileName(), IoQueryFileInformation(), NT_ERROR, NT_SUCCESS, NTSTATUS(), ObQueryNameString(), PAGED_CODE, PagedPool, UserMode, and USHORT.

Referenced by IopCreateObjectTypes().

    01821                    :
    01822
    01823     This function implements the query name procedure for the Object Manager
    01824     for querying the names of file objects.
    01825
    01826 Arguments:
    01827
    01828     Object - Pointer to the file object whose name is to be retrieved.
    01829
    01830     HasObjectName - Indicates whether or not the object has a name.
    01831
    01832     ObjectNameInfo - Buffer in which to return the name.
    01833
    01834     Length - Specifies the length of the output buffer, in bytes.
    01835
    01836     ReturnLength - Specifies the number of bytes actually returned in the
    01837         output buffer.
    01838
    01839 Return Value:
    01840
    01841     The function return value is the final status of the query operation.
    01842
    01843 --*/
    01844
    01845 {
    01846     NTSTATUS status;
    01847     ULONG lengthNeeded;
    01848     PFILE_OBJECT fileObject;
    01849     PUCHAR buffer;
    01850     PWSTR p;
    01851     POBJECT_NAME_INFORMATION deviceNameInfo;
    01852     PFILE_NAME_INFORMATION fileNameInfo;
    01853     ULONG length;
    01854
    01855     UNREFERENCED_PARAMETER( HasObjectName );
    01856
    01857     PAGED_CODE();
    01858
    01859     ASSERT( FIELD_OFFSET( FILE_NAME_INFORMATION, FileName ) < sizeof( OBJECT_NAME_INFORMATION ) );
    01860
    01861     //
    01862     // Ensure that the size of the output buffer is at least the minimum
    01863     // size required to include the basic object name information structure.
    01864     //
    01865
    01866     if (Length < sizeof( OBJECT_NAME_INFORMATION )) {
    01867         return STATUS_INFO_LENGTH_MISMATCH;
    01868         }
    01869
    01870     //
    01871     // Begin by allocating a buffer in which to build the name of the file.
    01872     //
    01873
    01874     buffer = ExAllocatePoolWithTag( PagedPool, Length, '  oI' );
    01875     if (!buffer) {
    01876         return STATUS_INSUFFICIENT_RESOURCES;
    01877         }
    01878
    01879     try {
    01880
    01881         //
    01882         // Query the name of the device on which the file is open.
    01883         //
    01884
    01885         fileObject = (PFILE_OBJECT) Object;
    01886         deviceNameInfo = (POBJECT_NAME_INFORMATION) buffer;
    01887
    01888         status = ObQueryNameString( (PVOID) fileObject->DeviceObject,
    01889                                     deviceNameInfo,
    01890                                     Length,
    01891                                     &lengthNeeded );
    01892         if (!NT_SUCCESS( status )) {
    01893             return status;
    01894             }
    01895
    01896         //
    01897         // Ensure that there is enough room in the output buffer to return the
    01898         // name and copy it.
    01899         //
    01900
    01901         RtlCopyMemory( ObjectNameInfo,
    01902                        deviceNameInfo,
    01903                        lengthNeeded > Length ? Length : lengthNeeded );
    01904         p = (PWSTR) (ObjectNameInfo + 1);
    01905         ObjectNameInfo->Name.Buffer = p;
    01906         p = (PWSTR) ((PCHAR) p + deviceNameInfo->Name.Length);
    01907
    01908         //
    01909         // If the buffer is already full, then return.
    01910         //
    01911
    01912         if (lengthNeeded > Length) {
    01913             return STATUS_BUFFER_OVERFLOW;
    01914             }
    01915
    01916         //
    01917         // Reset the state for the buffer to obtain the filename portion of the
    01918         // name and calculate the remaining length of the caller's buffer.  Note
    01919         // that in the following calculations, there are two assumptions and
    01920         // and dependencies:
    01921         //
    01922         //     1)  The above query of the device name's returned length needed
    01923         //         include a NULL character which will be included at the end
    01924         //         of the entire name.  This is included in the calculations
    01925         //         although it does not appear to be included.
    01926         //
    01927         //     2)  The sizeof the object name information buffer is assumed
    01928         //         (and guaranteed because it can never change) to be larger
    01929         //         than the filename offset in a file name information buffer.
    01930         //         Therefore it is known that the new length of the "buffer"
    01931         //         variable can be set to the remaining length plus at least 4.
    01932         //
    01933
    01934         fileNameInfo = (PFILE_NAME_INFORMATION) buffer;
    01935         length = Length - lengthNeeded;
    01936
    01937         length += FIELD_OFFSET( FILE_NAME_INFORMATION, FileName );
    01938
    01939         if (KeGetPreviousMode() == UserMode ||
    01940             !(fileObject->Flags & FO_SYNCHRONOUS_IO)) {
    01941
    01942             //
    01943             // Query the name of the file based using an intermediary buffer.
    01944             //
    01945
    01946             status = IoQueryFileInformation( fileObject,
    01947                                              FileNameInformation,
    01948                                              length,
    01949                                              (PVOID) fileNameInfo,
    01950                                              &lengthNeeded );
    01951             }
    01952         else {
    01953
    01954             //
    01955             // This is a kernel mode request for a file that was opened for
    01956             // synchronous I/O.  A special function that does not obtain the
    01957             // file object lock is required, otherwise the request may deadlock
    01958             // since the lock is probably already owned.
    01959             //
    01960
    01961             status = IopGetFileName( fileObject,
    01962                                      length,
    01963                                      fileNameInfo,
    01964                                      &lengthNeeded );
    01965             }
    01966
    01967         //
    01968         // If an error occurred attempting to obtain the filename return now.  Note
    01969         // that buffer overflow is a warning, not an error.
    01970         //
    01971
    01972         if (NT_ERROR( status )) {
    01973             if (status == STATUS_INVALID_PARAMETER ||
    01974                 status == STATUS_INVALID_DEVICE_REQUEST ||
    01975                 status == STATUS_NOT_IMPLEMENTED ||
    01976                 status == STATUS_INVALID_INFO_CLASS) {
    01977                 lengthNeeded = FIELD_OFFSET( FILE_NAME_INFORMATION, FileName );
    01978                 fileNameInfo->FileNameLength = 0;
    01979                 fileNameInfo->FileName[0] = OBJ_NAME_PATH_SEPARATOR;
    01980                 status = STATUS_SUCCESS;
    01981                 }
    01982             else {
    01983                 return status;
    01984                 }
    01985             }
    01986
    01987         //
    01988         // Set the remaining length of the caller's buffer as well as the total
    01989         // length needed to contain the entire name of the file.
    01990         //
    01991
    01992         length = lengthNeeded - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName );
    01993         lengthNeeded = (ULONG)((PUCHAR) p - (PUCHAR) ObjectNameInfo) + fileNameInfo->FileNameLength;
    01994
    01995         //
    01996         // Attempt to copy the name of the file into the output buffer.  Note
    01997         // that if the file name does not begin w/a '\', then it is not volume
    01998         // relative, so the name of the file cannot be expressed as the
    01999         // concatenation of the name of the device and the file.  Therefore an
    02000         // error is returned.
    02001         //
    02002         // The only example of this situation known at this time is when one
    02003         // opens a directory by file ID, and then opens a file relative to that
    02004         // directory.  When attempting to query the path, if the caller did not
    02005         // have traverse access to open the directory, then the only name that
    02006         // can be returned is the path name to the file from the directory, but
    02007         // the volume-relative name cannot be returned.  Therefore, the file
    02008         // system returns only the name of the directory and the path to the
    02009         // file, but this is not volume-relative so the only recourse is to
    02010         // return an error.
    02011         //
    02012         // Note that if the caller were to call NtQueryInformationFile and
    02013         // request FileNameInformation, then the name above named will be
    02014         // successfully returned from the file system.
    02015         //
    02016
    02017         if (fileNameInfo->FileName[0] != OBJ_NAME_PATH_SEPARATOR) {
    02018             return STATUS_OBJECT_PATH_INVALID;
    02019             }
    02020
    02021         RtlMoveMemory( p,
    02022                        fileNameInfo->FileName,
    02023                        length );
    02024         p = (PWSTR) ((PCH) p + length);
    02025         *p = '\0';
    02026         lengthNeeded += sizeof( WCHAR );
    02027
    02028         *ReturnLength = lengthNeeded;
    02029
    02030         length = (ULONG)((PUCHAR) p - (PUCHAR) ObjectNameInfo);
    02031         ObjectNameInfo->Name.Length = (USHORT) (length - sizeof( *ObjectNameInfo ));
    02032         ObjectNameInfo->Name.MaximumLength =  (USHORT) ((length - sizeof( *ObjectNameInfo )) + sizeof( WCHAR ));
    02033         }
    02034
    02035     finally {
    02036
    02037         //
    02038         // Finally, free the temporary buffer.
    02039         //
    02040
    02041         ExFreePool( buffer );
    02042         }
    02043
    02044     return status;
    02045 }

NTSTATUS IopQueryXxxInformation | ( | IN PFILE_OBJECT | FileObject,
|  | IN ULONG | InformationClass,
|  | IN ULONG | Length,
|  | OUT PVOID | Information,
|  | OUT PULONG | ReturnedLength,
|  | IN BOOLEAN | FileInformation
| ) |

Definition at line 5397 of file internal.c.

References _IRP::AssociatedIrp, Executive, FALSE, _IO_STACK_LOCATION::FileObject, _IRP::Flags, FO_ALERTABLE_IO, FO_SYNCHRONOUS_IO, IoAllocateIrp(), IoCallDriver, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAcquireFastLock, IopAcquireFileObjectLock(), IopAllocateIrpCleanup(), IopCancelAlertedRequest(), IopQueueThreadIrp, IopReleaseFileObjectLock, IRP_BUFFERED_IO, IRP_MJ_QUERY_INFORMATION, IRP_MJ_QUERY_VOLUME_INFORMATION, IRP_SYNCHRONOUS_API, KeClearEvent, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, _IRP::Overlay, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PsGetCurrentThread, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserEvent, _IRP::UserIosb, and VOID().

Referenced by IoQueryFileInformation(), and IoQueryVolumeInformation().

    05408                    :
    05409
    05410     This routine returns the requested information about a specified file
    05411     or volume.  The information returned is determined by the class that
    05412     is specified, and it is placed into the caller's output buffer.
    05413
    05414 Arguments:
    05415
    05416     FileObject - Supplies a pointer to the file object about which the requested
    05417         information is returned.
    05418
    05419     FsInformationClass - Specifies the type of information which should be
    05420         returned about the file/volume.
    05421
    05422     Length - Supplies the length of the buffer in bytes.
    05423
    05424     FsInformation - Supplies a buffer to receive the requested information
    05425         returned about the file.  This buffer must not be pageable and must
    05426         reside in system space.
    05427
    05428     ReturnedLength - Supplies a variable that is to receive the length of the
    05429         information written to the buffer.
    05430
    05431     FileInformation - Boolean that indicates whether the information requested
    05432         is for a file or a volume.
    05433
    05434 Return Value:
    05435
    05436     The status returned is the final completion status of the operation.
    05437
    05438 --*/
    05439
    05440 {
    05441     PIRP irp;
    05442     NTSTATUS status;
    05443     PDEVICE_OBJECT deviceObject;
    05444     KEVENT event;
    05445     PIO_STACK_LOCATION irpSp;
    05446     IO_STATUS_BLOCK localIoStatus;
    05447     BOOLEAN synchronousIo;
    05448
    05449     PAGED_CODE();
    05450
    05451     //
    05452     // Reference the file object here so that no special checks need be made
    05453     // in I/O completion to determine whether or not to dereference the file
    05454     // object.
    05455     //
    05456
    05457     ObReferenceObject( FileObject );
    05458
    05459     //
    05460     // Make a special check here to determine whether this is a synchronous
    05461     // I/O operation.  If it is, then wait here until the file is owned by
    05462     // the current thread.  If this is not a (serialized) synchronous I/O
    05463     // operation, then initialize the local event.
    05464     //
    05465
    05466     if (FileObject->Flags & FO_SYNCHRONOUS_IO) {
    05467
    05468         BOOLEAN interrupted;
    05469
    05470         if (!IopAcquireFastLock( FileObject )) {
    05471             status = IopAcquireFileObjectLock( FileObject,
    05472                                                KernelMode,
    05473                                                (BOOLEAN) ((FileObject->Flags & FO_ALERTABLE_IO) != 0),
    05474                                                &interrupted );
    05475             if (interrupted) {
    05476                 ObDereferenceObject( FileObject );
    05477                 return status;
    05478             }
    05479         }
    05480         KeClearEvent( &FileObject->Event );
    05481         synchronousIo = TRUE;
    05482     } else {
    05483         KeInitializeEvent( &event, SynchronizationEvent, FALSE );
    05484         synchronousIo = FALSE;
    05485     }
    05486
    05487     //
    05488     // Get the address of the target device object.
    05489     //
    05490
    05491     deviceObject = IoGetRelatedDeviceObject( FileObject );
    05492
    05493     //
    05494     // Allocate and initialize the I/O Request Packet (IRP) for this operation.
    05495     // The allocation is performed with an exception handler in case the
    05496     // caller does not have enough quota to allocate the packet.
    05497     //
    05498
    05499     irp = IoAllocateIrp( deviceObject->StackSize, TRUE );
    05500     if (!irp) {
    05501
    05502         //
    05503         // An IRP could not be allocated.  Cleanup and return an appropriate
    05504         // error status code.
    05505         //
    05506
    05507         IopAllocateIrpCleanup( FileObject, (PKEVENT) NULL );
    05508
    05509         return STATUS_INSUFFICIENT_RESOURCES;
    05510     }
    05511     irp->Tail.Overlay.OriginalFileObject = FileObject;
    05512     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    05513     irp->RequestorMode = KernelMode;
    05514
    05515     //
    05516     // Fill in the service independent parameters in the IRP.
    05517     //
    05518
    05519     if (synchronousIo) {
    05520         irp->UserEvent = (PKEVENT) NULL;
    05521     } else {
    05522         irp->UserEvent = &event;
    05523         irp->Flags = IRP_SYNCHRONOUS_API;
    05524     }
    05525     irp->UserIosb = &localIoStatus;
    05526     irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    05527
    05528     //
    05529     // Get a pointer to the stack location for the first driver.  This will be
    05530     // used to pass the original function codes and parameters.
    05531     //
    05532
    05533     irpSp = IoGetNextIrpStackLocation( irp );
    05534     irpSp->MajorFunction = FileInformation ?
    05535                            IRP_MJ_QUERY_INFORMATION :
    05536                            IRP_MJ_QUERY_VOLUME_INFORMATION;
    05537     irpSp->FileObject = FileObject;
    05538
    05539     //
    05540     // Set the system buffer address to the address of the caller's buffer and
    05541     // set the flags so that the buffer is not deallocated.
    05542     //
    05543
    05544     irp->AssociatedIrp.SystemBuffer = Information;
    05545     irp->Flags |= IRP_BUFFERED_IO;
    05546
    05547     //
    05548     // Copy the caller's parameters to the service-specific portion of the
    05549     // IRP.
    05550     //
    05551
    05552     if (FileInformation) {
    05553         irpSp->Parameters.QueryFile.Length = Length;
    05554         irpSp->Parameters.QueryFile.FileInformationClass = InformationClass;
    05555     } else {
    05556         irpSp->Parameters.QueryVolume.Length = Length;
    05557         irpSp->Parameters.QueryVolume.FsInformationClass = InformationClass;
    05558     }
    05559
    05560     //
    05561     // Insert the packet at the head of the IRP list for the thread.
    05562     //
    05563
    05564     IopQueueThreadIrp( irp );
    05565
    05566     //
    05567     // Now simply invoke the driver at its dispatch entry with the IRP.
    05568     //
    05569
    05570     status = IoCallDriver( deviceObject, irp );
    05571
    05572     //
    05573     // If this operation was a synchronous I/O operation, check the return
    05574     // status to determine whether or not to wait on the file object.  If
    05575     // the file object is to be waited on, wait for the operation to complete
    05576     // and obtain the final status from the file object itself.
    05577     //
    05578
    05579     if (synchronousIo) {
    05580         if (status == STATUS_PENDING) {
    05581             status = KeWaitForSingleObject( &FileObject->Event,
    05582                                             Executive,
    05583                                             KernelMode,
    05584                                             (BOOLEAN) ((FileObject->Flags & FO_ALERTABLE_IO) != 0),
    05585                                             (PLARGE_INTEGER) NULL );
    05586             if (status == STATUS_ALERTED) {
    05587                 IopCancelAlertedRequest( &FileObject->Event, irp );
    05588             }
    05589             status = FileObject->FinalStatus;
    05590         }
    05591         IopReleaseFileObjectLock( FileObject );
    05592
    05593     } else {
    05594
    05595         //
    05596         // This is a normal synchronous I/O operation, as opposed to a
    05597         // serialized synchronous I/O operation.  For this case, wait
    05598         // for the local event and copy the final status information
    05599         // back to the caller.
    05600         //
    05601
    05602         if (status == STATUS_PENDING) {
    05603             (VOID) KeWaitForSingleObject( &event,
    05604                                           Executive,
    05605                                           KernelMode,
    05606                                           FALSE,
    05607                                           (PLARGE_INTEGER) NULL );
    05608             status = localIoStatus.Status;
    05609         }
    05610     }
    05611
    05612     *ReturnedLength = (ULONG) localIoStatus.Information;
    05613     return status;
    05614 }

VOID IopQueueWorkRequest | ( | IN PIRP | Irp | ) |

VOID IopRaiseHardError | ( | IN PVOID | NormalContext,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2
| ) |

Definition at line 5617 of file internal.c.

References _IO_STACK_LOCATION::DeviceObject, _DEVICE_OBJECT::DriverObject, ExAllocatePool, ExFreePool(), ExRaiseHardError(), ExReadyForErrors, _IRP::Flags, _VPB::Flags, IO_DISK_INCREMENT, IoCompleteRequest, IoGetCurrentIrpStackLocation, IOP_ABORT, _IRP::IoStatus, IRP_INPUT_OPERATION, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_MOUNT_VOLUME, _DRIVER_OBJECT::MajorFunction, _IO_STACK_LOCATION::MajorFunction, MAXIMUM_VOLUME_LABEL_LENGTH, _IO_STACK_LOCATION::MinorFunction, NT_SUCCESS, NTSTATUS(), NULL, ObQueryNameString(), PagedPool, PERFINFO_DRIVER_MAJORFUNCTION_CALL, PERFINFO_DRIVER_MAJORFUNCTION_RETURN, RtlInitUnicodeString(), _VPB::VolumeLabel, _VPB::VolumeLabelLength, and VPB_MOUNTED.

Referenced by IopApcHardError(), and IoRaiseHardError().

    05625                    :
    05626
    05627     This routine raises a hard error popup in the context of the current
    05628     thread.  The APC was used to get into the context of this thread so that
    05629     the popup would be sent to the appropriate port.
    05630
    05631 Arguments:
    05632
    05633     NormalContext - Supplies a pointer to the I/O Request Packet (IRP) that
    05634         was initially used to request the operation that has failed.
    05635
    05636     SystemArgument1 - Supplies a pointer to the media's volume parameter block.
    05637         See IoRaiseHardError documentation for more information.
    05638
    05639     SystemArgument2 - Supplies a pointer to the real device object.  See
    05640         IoRaiseHardError documentation for more information.
    05641
    05642 Return Value:
    05643
    05644     None.
    05645
    05646 --*/
    05647
    05648 {
    05649     ULONG_PTR parameters[2];
    05650     ULONG numberOfParameters;
    05651     ULONG parameterMask;
    05652     ULONG response;
    05653     NTSTATUS status;
    05654     PIRP irp = (PIRP) NormalContext;
    05655     PVPB vpb = (PVPB) SystemArgument1;
    05656     PDEVICE_OBJECT realDeviceObject = (PDEVICE_OBJECT) SystemArgument2;
    05657
    05658     ULONG length;
    05659     POBJECT_NAME_INFORMATION objectName;
    05660
    05661     UNICODE_STRING labelName;
    05662
    05663     //
    05664     // Determine the name of the device and the volume label of the offending
    05665     // media.  Start by determining the size of the DeviceName, and allocate
    05666     // enough storage for both the ObjectName structure and the string
    05667     // because "that's the ways Steve's routine works".
    05668     //
    05669
    05670     ObQueryNameString( realDeviceObject, NULL, 0, &length );
    05671
    05672     if ((objectName = ExAllocatePool(PagedPool, length)) == NULL) {
    05673
    05674         status = STATUS_INSUFFICIENT_RESOURCES;
    05675
    05676     } else {
    05677
    05678         status = STATUS_SUCCESS;
    05679     }
    05680
    05681     if (!NT_SUCCESS( status ) ||
    05682         !NT_SUCCESS( status = ObQueryNameString( realDeviceObject,
    05683                                                  objectName,
    05684                                                  length,
    05685                                                  &response ) )) {
    05686
    05687         //
    05688         // Allocation of the pool to put up this popup did not work or
    05689         // something else failed, so there isn't really much that can be
    05690         // done here.  Simply return an error back to the user.
    05691         //
    05692
    05693         if (objectName) {
    05694             ExFreePool( objectName );
    05695         }
    05696
    05697         irp->IoStatus.Status = status;
    05698         irp->IoStatus.Information = 0;
    05699
    05700         IoCompleteRequest( irp, IO_DISK_INCREMENT );
    05701
    05702         return;
    05703     }
    05704
    05705     //
    05706     // The volume label has a max size of 32 characters (Unicode).  Convert
    05707     // it to a Unicode string for output in the popup message.
    05708     //
    05709
    05710     if (vpb != NULL && vpb->Flags & VPB_MOUNTED) {
    05711
    05712         labelName.Buffer = &vpb->VolumeLabel[0];
    05713         labelName.Length = vpb->VolumeLabelLength;
    05714         labelName.MaximumLength = MAXIMUM_VOLUME_LABEL_LENGTH;
    05715
    05716     } else {
    05717
    05718         RtlInitUnicodeString( &labelName, NULL );
    05719     }
    05720
    05721     //
    05722     // Different pop-ups have different printf formats.  Depending on the
    05723     // specific error value, adjust the parameters.
    05724     //
    05725
    05726     switch( irp->IoStatus.Status ) {
    05727
    05728     case STATUS_MEDIA_WRITE_PROTECTED:
    05729     case STATUS_WRONG_VOLUME:
    05730
    05731         numberOfParameters = 2;
    05732         parameterMask = 3;
    05733
    05734         parameters[0] = (ULONG_PTR) &labelName;
    05735         parameters[1] = (ULONG_PTR) &objectName->Name;
    05736
    05737         break;
    05738
    05739     case STATUS_DEVICE_NOT_READY:
    05740     case STATUS_IO_TIMEOUT:
    05741     case STATUS_NO_MEDIA_IN_DEVICE:
    05742     case STATUS_UNRECOGNIZED_MEDIA:
    05743
    05744         numberOfParameters = 1;
    05745         parameterMask = 1;
    05746
    05747         parameters[0] = (ULONG_PTR) &objectName->Name;
    05748         parameters[1] = 0;
    05749
    05750         break;
    05751
    05752     default:
    05753
    05754         numberOfParameters = 0;
    05755         parameterMask = 0;
    05756
    05757     }
    05758
    05759     //
    05760     // Simply raise the hard error.
    05761     //
    05762
    05763     if (ExReadyForErrors) {
    05764         status = ExRaiseHardError( irp->IoStatus.Status,
    05765                                    numberOfParameters,
    05766                                    parameterMask,
    05767                                    parameters,
    05768                                    OptionCancelTryContinue,
    05769                                    &response );
    05770
    05771     } else {
    05772
    05773         status = STATUS_UNSUCCESSFUL;
    05774         response = ResponseReturnToCaller;
    05775     }
    05776
    05777     //
    05778     // Free any pool or other resources that were allocated to output the
    05779     // popup.
    05780     //
    05781
    05782     ExFreePool( objectName );
    05783
    05784     //
    05785     // If there was a problem, or the user didn't want to retry, just
    05786     // complete the request.  Otherwise simply call the driver entry
    05787     // point and retry the IRP as if it had never been tried before.
    05788     //
    05789
    05790     if (!NT_SUCCESS( status ) || response != ResponseTryAgain) {
    05791
    05792         //
    05793         // Before completing the request, make one last check.  If this was
    05794         // a mount request, and the reason for the failure was t/o, no media,
    05795         // or unrecognized media, then set the Information field of the status
    05796         // block to indicate whether or not an abort was performed.
    05797         //
    05798
    05799         if (response == ResponseCancel) {
    05800             PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( irp );
    05801             if (irpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
    05802                 irpSp->MinorFunction == IRP_MN_MOUNT_VOLUME) {
    05803                 irp->IoStatus.Information = IOP_ABORT;
    05804             } else {
    05805                 irp->IoStatus.Status = STATUS_REQUEST_ABORTED;
    05806             }
    05807         }
    05808
    05809         //
    05810         // An error was incurred, so zero out the information field before
    05811         // completing the request if this was an input operation.  Otherwise,
    05812         // IopCompleteRequest will try to copy to the user's buffer.
    05813         //
    05814
    05815         if (irp->Flags & IRP_INPUT_OPERATION) {
    05816             irp->IoStatus.Information = 0;
    05817         }
    05818
    05819         IoCompleteRequest( irp, IO_DISK_INCREMENT );
    05820
    05821     } else {
    05822
    05823         PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( irp );
    05824         PDEVICE_OBJECT fsDeviceObject = irpSp->DeviceObject;
    05825         PDRIVER_OBJECT driverObject = fsDeviceObject->DriverObject;
    05826
    05827         //
    05828         // Retry the request from the top.
    05829         //
    05830
    05831         PERFINFO_DRIVER_MAJORFUNCTION_CALL(irp, irpSp, driverObject);
    05832
    05833         driverObject->MajorFunction[irpSp->MajorFunction]( fsDeviceObject,
    05834                                                            irp );
    05835
    05836         PERFINFO_DRIVER_MAJORFUNCTION_RETURN(irp, irpSp, driverObject);
    05837     }
    05838 }

VOID IopRaiseInformationalHardError | ( | IN PVOID | NormalContext,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2
| ) |

Definition at line 5841 of file internal.c.

References _IOP_HARD_ERROR_PACKET::ErrorStatus, ExFreePool(), ExRaiseHardError(), ExReadyForErrors, IopHardError, NULL, _IOP_HARD_ERROR_QUEUE::NumPendingApcPopups, _IOP_HARD_ERROR_PACKET::String, and VOID().

Referenced by IoRaiseInformationalHardError().

    05849                    :
    05850
    05851     This routine performs the actual pop-up.  It will called from either the
    05852     hard-error thread, or a APC routine in a user thread after exiting the
    05853     file system.
    05854
    05855 Arguments:
    05856
    05857     NormalContext - Contains the information for the pop-up
    05858
    05859     SystemArgument1 - not used.
    05860
    05861     SystemArgument1 - not used.
    05862
    05863 Return Value:
    05864
    05865     None.
    05866
    05867 --*/
    05868
    05869 {
    05870     ULONG parameterPresent;
    05871     ULONG_PTR errorParameter;
    05872     ULONG errorResponse;
    05873     PIOP_HARD_ERROR_PACKET hardErrorPacket;
    05874
    05875     UNREFERENCED_PARAMETER( SystemArgument1 );
    05876     UNREFERENCED_PARAMETER( SystemArgument2 );
    05877
    05878     hardErrorPacket = (PIOP_HARD_ERROR_PACKET) NormalContext;
    05879
    05880     //
    05881     // Simply raise the hard error if the system is ready to accept one.
    05882     //
    05883
    05884     errorParameter = (ULONG_PTR) &hardErrorPacket->String;
    05885
    05886     parameterPresent = (hardErrorPacket->String.Buffer != NULL);
    05887
    05888     if (ExReadyForErrors) {
    05889         (VOID) ExRaiseHardError( hardErrorPacket->ErrorStatus,
    05890                                  parameterPresent,
    05891                                  parameterPresent,
    05892                                  parameterPresent ? &errorParameter : NULL,
    05893                                  OptionOk,
    05894                                  &errorResponse );
    05895     }
    05896
    05897     //
    05898     // Now free the packet and the buffer, if one was specified.
    05899     //
    05900
    05901     if (hardErrorPacket->String.Buffer) {
    05902         ExFreePool( hardErrorPacket->String.Buffer );
    05903     }
    05904
    05905     ExFreePool( hardErrorPacket );
    05906     InterlockedDecrement(&IopHardError.NumPendingApcPopups);
    05907 }

VOID IopReadyDeviceObjects | ( | IN PDRIVER_OBJECT | DriverObject | ) |

Definition at line 5910 of file internal.c.

References DO_DEVICE_INITIALIZING, DRVO_INITIALIZED, _DEVICE_OBJECT::Flags, _DEVICE_OBJECT::NextDevice, and PAGED_CODE.

Referenced by IopInitializeBuiltinDriver(), and IopLoadDriver().

    05916                    :
    05917
    05918     This routine is invoked to mark all of the device objects owned by the
    05919     specified driver as having been fully initialized and therefore ready
    05920     for access by other drivers/clients.
    05921
    05922 Arguments:
    05923
    05924     DriverObject - Supplies a pointer to the driver object for the driver
    05925         whose devices are to be marked as being "ready".
    05926
    05927 Return Value:
    05928
    05929     None.
    05930
    05931 --*/
    05932
    05933 {
    05934     PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
    05935
    05936     PAGED_CODE();
    05937
    05938     //
    05939     // Loop through all of the driver's device objects, clearing the
    05940     // DO_DEVICE_INITIALIZING flag.
    05941     //
    05942
    05943     DriverObject->Flags |= DRVO_INITIALIZED;
    05944     while (deviceObject) {
    05945         deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    05946         deviceObject = deviceObject->NextDevice;
    05947     }
    05948 }

NTSTATUS IopReportResourceUsage | ( | IN PUNICODE_STRING DriverClassName | OPTIONAL,
|  | IN PDRIVER_OBJECT | DriverObject,
|  | IN PCM_RESOURCE_LIST DriverList | OPTIONAL,
|  | IN ULONG DriverListSize | OPTIONAL,
|  | IN PDEVICE_OBJECT DeviceObject | OPTIONAL,
|  | IN PCM_RESOURCE_LIST DeviceList | OPTIONAL,
|  | IN ULONG DeviceListSize | OPTIONAL,
|  | IN BOOLEAN | OverrideConflict,
|  | OUT PBOOLEAN | ConflictDetected
| ) |

BOOLEAN IopSafebootDriverLoad | ( | PUNICODE_STRING | DriverId | ) |

Definition at line 8822 of file internal.c.

References CmRegistryMachineSystemCurrentControlSetControlSafeBoot, ExAllocatePool, ExFreePool(), FALSE, InitSafeBootMode, IopOpenRegistryKey(), L, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, PagedPool, RtlAppendUnicodeStringToString(), RtlAppendUnicodeToString(), RtlCopyUnicodeString(), RtlInitUnicodeString(), and TRUE.

Referenced by IopCallDriverAddDevice(), and IopLoadDriver().

    08827                    :
    08828
    08829     Checks to see if a driver or service is included
    08830     in the current safeboot registry section.
    08831
    08832 Arguments:
    08833
    08834     DriverId - Specifies which driver is to be validated.
    08835         The string should contain a driver executable name
    08836         like foo.sys or a GUID for a pnp driver class.
    08837
    08838 Return Value:
    08839
    08840     TRUE    - driver/service is in the registry
    08841     FALSE   - driver/service is NOT in the registry
    08842
    08843 --*/
    08844 {
    08845     NTSTATUS status;
    08846     HANDLE hSafeBoot,hGuid;
    08847     UNICODE_STRING safeBootKey;
    08848     UNICODE_STRING SafeBootTypeString;
    08849
    08850
    08851
    08852     //
    08853     // set the first part of the registry key name
    08854     //
    08855
    08856     switch (InitSafeBootMode) {
    08857         case SAFEBOOT_MINIMAL:
    08858             RtlInitUnicodeString(&SafeBootTypeString,SAFEBOOT_MINIMAL_STR_W);
    08859             break;
    08860
    08861         case SAFEBOOT_NETWORK:
    08862             RtlInitUnicodeString(&SafeBootTypeString,SAFEBOOT_NETWORK_STR_W);
    08863             break;
    08864
    08865         case SAFEBOOT_DSREPAIR:
    08866             return TRUE;
    08867
    08868         default:
    08869             KdPrint(("SAFEBOOT: invalid safeboot option = %d\n",InitSafeBootMode));
    08870             return FALSE;
    08871     }
    08872
    08873     safeBootKey.Length = 0;
    08874     safeBootKey.MaximumLength = DriverId->Length + SafeBootTypeString.Length + (4*sizeof(WCHAR));
    08875     safeBootKey.Buffer = (PWCHAR)ExAllocatePool(PagedPool,safeBootKey.MaximumLength);
    08876     if (!safeBootKey.Buffer) {
    08877         KdPrint(("SAFEBOOT: could not allocate pool\n"));
    08878         return FALSE;
    08879     }
    08880
    08881     RtlCopyUnicodeString(&safeBootKey,&SafeBootTypeString);
    08882     status = RtlAppendUnicodeToString(&safeBootKey,L"\\");
    08883     if (!NT_SUCCESS(status)) {
    08884         ExFreePool (safeBootKey.Buffer);
    08885         KdPrint(("SAFEBOOT: could not create registry key string = %x\n",status));
    08886         return FALSE;
    08887     }
    08888     status = RtlAppendUnicodeStringToString(&safeBootKey,DriverId);
    08889     if (!NT_SUCCESS(status)) {
    08890         ExFreePool (safeBootKey.Buffer);
    08891         KdPrint(("SAFEBOOT: could not create registry key string = %x\n",status));
    08892         return FALSE;
    08893     }
    08894
    08895     status = IopOpenRegistryKey (
    08896         &hSafeBoot,
    08897         NULL,
    08898         &CmRegistryMachineSystemCurrentControlSetControlSafeBoot,
    08899         KEY_ALL_ACCESS,
    08900         FALSE
    08901         );
    08902     if (NT_SUCCESS(status)) {
    08903         status = IopOpenRegistryKey (
    08904             &hGuid,
    08905             hSafeBoot,
    08906             &safeBootKey,
    08907             KEY_ALL_ACCESS,
    08908             FALSE
    08909             );
    08910         NtClose(hSafeBoot);
    08911         if (NT_SUCCESS(status)) {
    08912             NtClose(hGuid);
    08913             ExFreePool(safeBootKey.Buffer);
    08914             return TRUE;
    08915         }
    08916     }
    08917
    08918     ExFreePool(safeBootKey.Buffer);
    08919
    08920     return FALSE;
    08921 }

NTSTATUS IopSetEaOrQuotaInformationFile | ( | IN HANDLE | FileHandle,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PVOID | Buffer,
|  | IN ULONG | Length,
|  | IN BOOLEAN | SetEa
| ) |

Definition at line 6326 of file internal.c.

References _IRP::AssociatedIrp, Buffer, DO_BUFFERED_IO, DO_DIRECT_IO, ExAllocatePool, ExAllocatePoolWithQuota, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), ExRaiseStatus(), FALSE, _IO_STACK_LOCATION::FileObject, _DEVICE_OBJECT::Flags, _IRP::Flags, FO_ALERTABLE_IO, FO_SYNCHRONOUS_IO, IoAllocateIrp(), IoAllocateMdl(), IoCheckEaBufferValidity(), IoCheckQuotaBufferValidity(), IoFileObjectType, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAcquireFastLock, IopAcquireFileObjectLock(), IopAllocateIrpCleanup(), IopExceptionCleanup(), IopSynchronousApiServiceTail(), IopSynchronousServiceTail(), IoReadAccess, IRP_BUFFERED_IO, IRP_DEALLOCATE_BUFFER, IRP_MJ_SET_EA, IRP_MJ_SET_QUOTA, IRP_SYNCHRONOUS_API, KeClearEvent, KeInitializeEvent, KernelMode, KPROCESSOR_MODE, _IO_STACK_LOCATION::MajorFunction, MmProbeAndLockPages(), NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), OtherTransfer, _IRP::Overlay, PAGED_CODE, _IO_STACK_LOCATION::Parameters, ProbeForRead, ProbeForWriteIoStatus, PsGetCurrentThread, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserBuffer, _IRP::UserEvent, and _IRP::UserIosb.

Referenced by NtSetQuotaInformationFile().

    06336                    :
    06337
    06338     This routine is invoked by the NtSetEa[Quota]InformationFile system services
    06339     to either modify the EAs on a file or the quota entries on a volume.  All of
    06340     the specified entries in the buffer are made to the file or volume.
    06341
    06342 Arguments:
    06343
    06344     FileHandle - Supplies a handle to the file/volume for which the entries are
    06345         to be applied.
    06346
    06347     IoStatusBlock - Address of the caller's I/O status block.
    06348
    06349     Buffer - Supplies a buffer containing the entries to be added/modified.
    06350
    06351     Length - Supplies the length, in bytes, of the buffer.
    06352
    06353     SetEa - A BOOLEAN that indicates whether to change the EAs on a file or
    06354         the quota entries on the volume.
    06355
    06356 Return Value:
    06357
    06358     The status returned is the final completion status of the operation.
    06359
    06360 --*/
    06361
    06362 {
    06363     PIRP irp;
    06364     NTSTATUS status;
    06365     PFILE_OBJECT fileObject;
    06366     PDEVICE_OBJECT deviceObject;
    06367     PKEVENT event = (PKEVENT) NULL;
    06368     KPROCESSOR_MODE requestorMode;
    06369     PIO_STACK_LOCATION irpSp;
    06370     IO_STATUS_BLOCK localIoStatus;
    06371     BOOLEAN synchronousIo;
    06372
    06373     PAGED_CODE();
    06374
    06375     //
    06376     // Get the previous mode;  i.e., the mode of the caller.
    06377     //
    06378
    06379     requestorMode = KeGetPreviousMode();
    06380
    06381     if (requestorMode != KernelMode) {
    06382
    06383         //
    06384         // The caller's access mode is user, so probe each of the arguments
    06385         // and capture them as necessary.  If any failures occur, the condition
    06386         // handler will be invoked to handle them.  It will simply cleanup and
    06387         // return an access violation status code back to the system service
    06388         // dispatcher.
    06389         //
    06390
    06391         try {
    06392
    06393             //
    06394             // The IoStatusBlock parameter must be writeable by the caller.
    06395             //
    06396
    06397             ProbeForWriteIoStatus( IoStatusBlock);
    06398
    06399             //
    06400             // The Buffer parameter must be readable by the caller.
    06401             //
    06402
    06403             ProbeForRead( Buffer, Length, sizeof( ULONG ) );
    06404
    06405         } except(EXCEPTION_EXECUTE_HANDLER) {
    06406
    06407             //
    06408             // An exception was incurred while probing the caller's parameters.
    06409             // Cleanup and return an appropriate error status code.
    06410             //
    06411
    06412             return GetExceptionCode();
    06413         }
    06414     }
    06415
    06416     //
    06417     // There were no blatant errors so far, so reference the file object so
    06418     // the target device object can be found.  Note that if the handle does
    06419     // not refer to a file object, or if the caller does not have the required
    06420     // access to the file, then it will fail.
    06421     //
    06422
    06423     status = ObReferenceObjectByHandle( FileHandle,
    06424                                         SetEa ? FILE_WRITE_EA : FILE_WRITE_DATA,
    06425                                         IoFileObjectType,
    06426                                         requestorMode,
    06427                                         (PVOID *) &fileObject,
    06428                                         NULL );
    06429     if (!NT_SUCCESS( status )) {
    06430         return status;
    06431     }
    06432
    06433     //
    06434     // Make a special check here to determine whether this is a synchronous
    06435     // I/O operation.  If it is, then wait here until the file is owned by
    06436     // the current thread.  If this is not a (serialized) synchronous I/O
    06437     // operation, then allocate and initialize the local event.
    06438     //
    06439
    06440     if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    06441
    06442         BOOLEAN interrupted;
    06443
    06444         if (!IopAcquireFastLock( fileObject )) {
    06445             status = IopAcquireFileObjectLock( fileObject,
    06446                                                requestorMode,
    06447                                                (BOOLEAN) ((fileObject->Flags & FO_ALERTABLE_IO) != 0),
    06448                                                &interrupted );
    06449             if (interrupted) {
    06450                 ObDereferenceObject( fileObject );
    06451                 return status;
    06452             }
    06453         }
    06454         synchronousIo = TRUE;
    06455     } else {
    06456
    06457         //
    06458         // This is a synchronous API being invoked for a file that is opened
    06459         // for asynchronous I/O.  This means that this system service is
    06460         // to synchronize the completion of the operation before returning
    06461         // to the caller.  A local event is used to do this.
    06462         //
    06463
    06464         event = ExAllocatePool( NonPagedPool, sizeof( KEVENT ) );
    06465         if (!event) {
    06466             ObDereferenceObject( fileObject );
    06467             return STATUS_INSUFFICIENT_RESOURCES;
    06468         }
    06469         KeInitializeEvent( event, SynchronizationEvent, FALSE );
    06470         synchronousIo = FALSE;
    06471     }
    06472
    06473     //
    06474     // Set the file object to the Not-Signaled state.
    06475     //
    06476
    06477     KeClearEvent( &fileObject->Event );
    06478
    06479     //
    06480     // Get the address of the target device object.
    06481     //
    06482
    06483     deviceObject = IoGetRelatedDeviceObject( fileObject );
    06484
    06485     //
    06486     // Allocate and initialize the I/O Request Packet (IRP) for this operation.
    06487     // The allocation is performed with an exception handler in case the
    06488     // caller does not have enough quota to allocate the packet.
    06489
    06490     irp = IoAllocateIrp( deviceObject->StackSize, TRUE );
    06491     if (!irp) {
    06492
    06493         //
    06494         // An IRP could not be allocated.  Cleanup and return an appropriate
    06495         // error status code.
    06496         //
    06497
    06498         if (!(fileObject->Flags & FO_SYNCHRONOUS_IO)) {
    06499             ExFreePool( event );
    06500         }
    06501
    06502         IopAllocateIrpCleanup( fileObject, (PKEVENT) NULL );
    06503
    06504         return STATUS_INSUFFICIENT_RESOURCES;
    06505     }
    06506     irp->Tail.Overlay.OriginalFileObject = fileObject;
    06507     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    06508     irp->RequestorMode = requestorMode;
    06509
    06510     //
    06511     // Fill in the service independent parameters in the IRP.
    06512     //
    06513
    06514     if (synchronousIo) {
    06515         irp->UserEvent = (PKEVENT) NULL;
    06516         irp->UserIosb = IoStatusBlock;
    06517     } else {
    06518         irp->UserEvent = event;
    06519         irp->UserIosb = &localIoStatus;
    06520         irp->Flags = IRP_SYNCHRONOUS_API;
    06521     }
    06522     irp->Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE) NULL;
    06523
    06524     //
    06525     // Get a pointer to the stack location for the first driver.  This will be
    06526     // used to pass the original function codes and parameters.
    06527     //
    06528
    06529     irpSp = IoGetNextIrpStackLocation( irp );
    06530     irpSp->MajorFunction = SetEa ? IRP_MJ_SET_EA : IRP_MJ_SET_QUOTA;
    06531     irpSp->FileObject = fileObject;
    06532
    06533     //
    06534     // Now determine whether this driver expects to have data buffered to it
    06535     // or whether it performs direct I/O.  This is based on the DO_BUFFERED_IO
    06536     // flag in the device object.  if the flag is set, then a system buffer is
    06537     // allocated and driver's data is copied to it.  If the DO_DIRECT_IO flag
    06538     // is set in the device object, then a Memory Descriptor List (MDL) is
    06539     // allocated and the caller's buffer is locked down using it.  Finally, if
    06540     // the driver specifies neither of the flags, then simply pass the address
    06541     // and length of the buffer and allow the driver to perform all of the
    06542     // checking and buffering if any is required.
    06543     //
    06544
    06545     if (deviceObject->Flags & DO_BUFFERED_IO) {
    06546
    06547         PVOID systemBuffer;
    06548         ULONG errorOffset;
    06549
    06550         //
    06551         // The driver wishes the caller's buffer to be copied into an
    06552         // intermediary buffer.  Allocate the system buffer and specify
    06553         // that it should be deallocated on completion.  Also check to
    06554         // ensure that the caller's EA list or quota list is valid.  All
    06555         // of this is performed within an exception handler that will perform
    06556         // cleanup if the operation fails.
    06557         //
    06558
    06559         try {
    06560
    06561             //
    06562             // Allocate the intermediary system buffer and charge the caller
    06563             // quota for its allocation.  Copy the caller's buffer into the
    06564             // system buffer and check to ensure that it is valid.
    06565             //
    06566
    06567             systemBuffer = ExAllocatePoolWithQuota( NonPagedPool, Length );
    06568
    06569             irp->AssociatedIrp.SystemBuffer = systemBuffer;
    06570
    06571             RtlCopyMemory( systemBuffer, Buffer, Length );
    06572
    06573             if (SetEa) {
    06574                 status = IoCheckEaBufferValidity( systemBuffer,
    06575                                                   Length,
    06576                                                   &errorOffset );
    06577             } else {
    06578                 status = IoCheckQuotaBufferValidity( systemBuffer,
    06579                                                      Length,
    06580                                                      &errorOffset );
    06581             }
    06582
    06583             if (!NT_SUCCESS( status )) {
    06584                 IoStatusBlock->Status = status;
    06585                 IoStatusBlock->Information = errorOffset;
    06586                 ExRaiseStatus( status );
    06587             }
    06588
    06589         } except(EXCEPTION_EXECUTE_HANDLER) {
    06590
    06591             //
    06592             // An exception was incurred while allocating the buffer, copying
    06593             // the caller's data into it, or walking the buffer.  Determine
    06594             // what happened, cleanup, and return an appropriate error status
    06595             // code.
    06596             //
    06597
    06598             IopExceptionCleanup( fileObject,
    06599                                  irp,
    06600                                  (PKEVENT) NULL,
    06601                                  event );
    06602
    06603             return GetExceptionCode();
    06604
    06605         }
    06606
    06607         //
    06608         // Set the flags so that the completion code knows to deallocate the
    06609         // buffer.
    06610         //
    06611
    06612         irp->Flags |= IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
    06613
    06614     } else if (deviceObject->Flags & DO_DIRECT_IO) {
    06615
    06616         PMDL mdl;
    06617
    06618         //
    06619         // This is a direct I/O operation.  Allocate an MDL and invoke the
    06620         // memory management routine to lock the buffer into memory.  This is
    06621         // done using an exception handler that will perform cleanup if the
    06622         // operation fails.
    06623         //
    06624
    06625         mdl = (PMDL) NULL;
    06626
    06627         try {
    06628
    06629             //
    06630             // Allocate an MDL, charging quota for it, and hang it off of the
    06631             // IRP.  Probe and lock the pages associated with the caller's
    06632             // buffer for read access and fill in the MDL with the PFNs of those
    06633             // pages.
    06634             //
    06635
    06636             mdl = IoAllocateMdl( Buffer, Length, FALSE, TRUE, irp );
    06637             if (!mdl) {
    06638                 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
    06639             }
    06640             MmProbeAndLockPages( mdl, requestorMode, IoReadAccess );
    06641
    06642         } except(EXCEPTION_EXECUTE_HANDLER) {
    06643
    06644             //
    06645             // An exception was incurred while either probing the caller's
    06646             // buffer or allocating the MDL.  Determine what actually happened,
    06647             // clean everything up, and return an appropriate error status code.
    06648             //
    06649
    06650             IopExceptionCleanup( fileObject,
    06651                                  irp,
    06652                                  (PKEVENT) NULL,
    06653                                  event );
    06654
    06655             return GetExceptionCode();
    06656
    06657         }
    06658
    06659     } else {
    06660
    06661         //
    06662         // Pass the address of the user's buffer so the driver has access to
    06663         // it.  It is now the driver's responsibility to do everything.
    06664         //
    06665
    06666         irp->UserBuffer = Buffer;
    06667
    06668     }
    06669
    06670     //
    06671     // Copy the caller's parameters to the service-specific portion of the
    06672     // IRP.
    06673     //
    06674
    06675     if (SetEa) {
    06676         irpSp->Parameters.SetEa.Length = Length;
    06677     } else {
    06678         irpSp->Parameters.SetQuota.Length = Length;
    06679     }
    06680
    06681     //
    06682     // Queue the packet, call the driver, and synchronize appropriately with
    06683     // I/O completion.
    06684     //
    06685
    06686     status = IopSynchronousServiceTail( deviceObject,
    06687                                         irp,
    06688                                         fileObject,
    06689                                         FALSE,
    06690                                         requestorMode,
    06691                                         synchronousIo,
    06692                                         OtherTransfer );
    06693
    06694     //
    06695     // If the file for this operation was not opened for synchronous I/O, then
    06696     // synchronization of completion of the I/O operation has not yet occurred
    06697     // since the allocated event must be used for synchronous APIs on files
    06698     // opened for asynchronous I/O.  Synchronize the completion of the I/O
    06699     // operation now.
    06700     //
    06701
    06702     if (!synchronousIo) {
    06703
    06704         status = IopSynchronousApiServiceTail( status,
    06705                                                event,
    06706                                                irp,
    06707                                                requestorMode,
    06708                                                &localIoStatus,
    06709                                                IoStatusBlock );
    06710     }
    06711
    06712     return status;
    06713 }

NTSTATUS IopSetRemoteLink | ( | IN PFILE_OBJECT | FileObject,
|  | IN PFILE_OBJECT DestinationFileObject | OPTIONAL,
|  | IN PFILE_TRACKING_INFORMATION FileInformation | OPTIONAL
| ) |

Definition at line 6716 of file internal.c.

References _IRP::AssociatedIrp, Executive, FALSE, _IO_STACK_LOCATION::FileObject, _IRP::Flags, IoBuildDeviceIoControlRequest(), IoCallDriver, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_KERNEL_CALL, IRP_SYNCHRONOUS_API, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, ObReferenceObject, PAGED_CODE, _IO_STACK_LOCATION::Parameters, _IRP::Tail, and _REMOTE_LINK_BUFFER::TrackingInformation.

Referenced by IopTrackLink().

    06724                    :
    06725
    06726     This routine is invoked to remote an NtSetInformationFile API call via an
    06727     FSCTL to the Redirector.  The call will cause the remote system to perform
    06728     the service call to track the link for a file which was just moved.
    06729
    06730 Arguments:
    06731
    06732     FileObject - Supplies the file object for the file that was moved.
    06733
    06734     DestinationFileObject - Optionally supplies the file object for the new
    06735         destination location for the file.
    06736
    06737     FileInformation - Optionally supplies the volume and file object IDs of
    06738         the target file.
    06739
    06740 Return Value:
    06741
    06742     The final function value is the final completion status of the operation.
    06743
    06744 --*/
    06745
    06746 {
    06747     REMOTE_LINK_BUFFER remoteBuffer;
    06748     IO_STATUS_BLOCK ioStatus;
    06749     NTSTATUS status;
    06750     PIRP irp;
    06751     KEVENT event;
    06752     PIO_STACK_LOCATION irpSp;
    06753     PDEVICE_OBJECT deviceObject;
    06754     ULONG length = 0;
    06755
    06756     PAGED_CODE();
    06757
    06758     //
    06759     // Initialize the event structure to synchronize completion of the I/O
    06760     // request.
    06761     //
    06762
    06763     KeInitializeEvent( &event,
    06764                        NotificationEvent,
    06765                        FALSE );
    06766
    06767     //
    06768     // Build an I/O Request Packet to be sent to the file system driver to get
    06769     // the volume ID.
    06770     //
    06771
    06772     deviceObject = IoGetRelatedDeviceObject( FileObject );
    06773
    06774     irp = IoBuildDeviceIoControlRequest( FSCTL_LMR_SET_LINK_TRACKING_INFORMATION,
    06775                                          deviceObject,
    06776                                          NULL,
    06777                                          0,
    06778                                          NULL,
    06779                                          0,
    06780                                          FALSE,
    06781                                          &event,
    06782                                          &ioStatus );
    06783     if (!irp) {
    06784         return STATUS_INSUFFICIENT_RESOURCES;
    06785     }
    06786
    06787     //
    06788     // Initialize the remote link buffer according to the input information.
    06789     //
    06790
    06791     if (DestinationFileObject) {
    06792
    06793         // The FileObject and DestinationFileObject are on the same machine
    06794         remoteBuffer.TrackingInformation.TargetFileObject = DestinationFileObject;
    06795
    06796         if (FileInformation) {
    06797             // Copy the ObjectInformation from the FileInformation buffer into
    06798             // the TargetLinkTrackingInformationBuffer.  Set 'length' to include
    06799             // this buffer.
    06800
    06801             remoteBuffer.TrackingInformation.TargetLinkTrackingInformationLength
    06802                 = length = FileInformation->ObjectInformationLength;
    06803             RtlCopyMemory( &remoteBuffer.TrackingInformation.TargetLinkTrackingInformationBuffer,
    06804                            FileInformation->ObjectInformation,
    06805                            length );
    06806         } else {
    06807             // We don't have any extra FileInformation.
    06808             remoteBuffer.TrackingInformation.TargetLinkTrackingInformationLength = 0;
    06809         }
    06810
    06811         // Increment the length to include the size of the non-optional fields in
    06812         // REMOTE_LINK_TRACKING_INFORMATION.
    06813         length += sizeof( PFILE_OBJECT ) + sizeof( ULONG );
    06814
    06815     } else {
    06816         // There's no DestinationFileObject, so all the necessary information is in the
    06817         // FileInformation structure.
    06818         length = FileInformation->ObjectInformationLength + sizeof( HANDLE ) + sizeof( ULONG );
    06819         RtlCopyMemory( &remoteBuffer.TrackingInformation,
    06820                        FileInformation,
    06821                        length );
    06822         remoteBuffer.TrackingInformation.TargetFileObject = NULL;
    06823     }
    06824
    06825     //
    06826     // Fill in the remainder of the IRP to retrieve the object ID for the
    06827     // file.
    06828     //
    06829
    06830     irp->Flags |= IRP_SYNCHRONOUS_API;
    06831     irp->AssociatedIrp.SystemBuffer = &remoteBuffer;
    06832     irp->Tail.Overlay.OriginalFileObject = FileObject;
    06833
    06834     irpSp = IoGetNextIrpStackLocation( irp );
    06835     irpSp->FileObject = FileObject;
    06836     irpSp->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
    06837     irpSp->MinorFunction = IRP_MN_KERNEL_CALL;
    06838     irpSp->Parameters.FileSystemControl.InputBufferLength = length;
    06839
    06840     //
    06841     // Take out another reference to the file object to guarantee that it does
    06842     // not get deleted.
    06843     //
    06844
    06845     ObReferenceObject( FileObject );
    06846
    06847     //
    06848     // Call the driver to get the request.
    06849     //
    06850
    06851     status = IoCallDriver( deviceObject, irp );
    06852
    06853     //
    06854     // Synchronize completion of the request.
    06855     //
    06856
    06857     if (status == STATUS_PENDING) {
    06858         status = KeWaitForSingleObject( &event,
    06859                                         Executive,
    06860                                         KernelMode,
    06861                                         FALSE,
    06862                                         (PLARGE_INTEGER) NULL );
    06863         status = ioStatus.Status;
    06864     }
    06865
    06866     return status;
    06867 }

NTSTATUS IopSetupRemoteBootCard | ( | IN PLOADER_PARAMETER_BLOCK | LoaderBlock,
|  | IN HANDLE | UniqueIdHandle,
|  | IN PUNICODE_STRING | UnicodeDeviceInstance
| ) |

Definition at line 1982 of file netboot.c.

References CmRegistryMachineSystemCurrentControlSet, CmRegistryMachineSystemCurrentControlSetControlClass, FALSE, IopOpenRegistryKey(), IopRemoteBootCardInitialized, L, _SETUP_LOADER_BLOCK::NetbootCardDriverName, _SETUP_LOADER_BLOCK::NetbootCardHardwareId, _SETUP_LOADER_BLOCK::NetbootCardInfo, _SETUP_LOADER_BLOCK::NetbootCardRegistry, _SETUP_LOADER_BLOCK::NetbootCardServiceName, NT_SUCCESS, NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlEqualUnicodeString(), RtlInitAnsiString(), RtlInitString(), RtlInitUnicodeString(), strlen(), TITLE_INDEX_VALUE, and TRUE.

Referenced by IopProcessNewDeviceNode().

    01990                    :
    01991
    01992     This function modifies the registry to set up the netboot card.
    01993     We must do this here since the card is needed to boot, we can't
    01994     wait for the class installer to run.
    01995
    01996     THIS ASSUMES THAT IOREMOTEBOOTCLIENT IS TRUE.
    01997
    01998 Arguments:
    01999
    02000     LoaderBlock - Supplies a pointer to the loader parameter block that was
    02001         created by the OS Loader.
    02002
    02003     UniqueIdHandle - A handle to the device's unique node under the
    02004         Enum key.
    02005
    02006     UnicodeDeviceInstance - The device instance assigned to the device.
    02007
    02008 Return Value:
    02009
    02010     Status of the operation.
    02011
    02012 --*/
    02013
    02014 {
    02015     PSETUP_LOADER_BLOCK setupLoaderBlock;
    02016     UNICODE_STRING unicodeName, pnpInstanceId, keyName;
    02017     HANDLE tmpHandle;
    02018     HANDLE parametersHandle = NULL;
    02019     HANDLE currentControlSetHandle = NULL;
    02020     HANDLE remoteBootHandle = NULL;
    02021     HANDLE instanceHandle = NULL;
    02022     PWCHAR componentIdBuffer, curComponentIdLoc;
    02023     PCHAR registryList;
    02024     ULONG componentIdLength;
    02025     WCHAR tempNameBuffer[32];
    02026     WCHAR tempValueBuffer[128];
    02027     NTSTATUS status;
    02028     ULONG tmpValue, length;
    02029     PKEY_VALUE_PARTIAL_INFORMATION keyValue;
    02030     PKEY_VALUE_BASIC_INFORMATION keyValueBasic;
    02031     UCHAR dataBuffer[FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + 128];
    02032     ULONG enumerateIndex;
    02033     OBJECT_ATTRIBUTES objectAttributes;
    02034     ULONG disposition;
    02035
    02036     //
    02037     // If we already think we have initialized a remote boot card, then
    02038     // exit (should not really happen once we identify cards using the
    02039     // bus/slot.
    02040     //
    02041
    02042     if (IopRemoteBootCardInitialized) {
    02043         return STATUS_SUCCESS;
    02044     }
    02045
    02046     //
    02047     // setupLoaderBlock will always be non-NULL if we are
    02048     // remote booting, even if we are not in setup.
    02049     //
    02050
    02051     setupLoaderBlock = LoaderBlock->SetupLoaderBlock;
    02052
    02053     //
    02054     // Open the current control set.
    02055     //
    02056
    02057     status = IopOpenRegistryKey(&currentControlSetHandle,
    02058                                 NULL,
    02059                                 &CmRegistryMachineSystemCurrentControlSet,
    02060                                 KEY_ALL_ACCESS,
    02061                                 FALSE
    02062                                 );
    02063
    02064     if (!NT_SUCCESS(status)) {
    02065         goto cleanup;
    02066     }
    02067
    02068     //
    02069     // Open the Control\RemoteBoot key, which may not exist.
    02070     //
    02071
    02072     PiWstrToUnicodeString(&unicodeName, L"Control\\RemoteBoot");
    02073
    02074     InitializeObjectAttributes(&objectAttributes,
    02075                                &unicodeName,
    02076                                OBJ_CASE_INSENSITIVE,
    02077                                currentControlSetHandle,
    02078                                (PSECURITY_DESCRIPTOR)NULL
    02079                                );
    02080
    02081     status = ZwCreateKey(&remoteBootHandle,
    02082                          KEY_ALL_ACCESS,
    02083                          &objectAttributes,
    02084                          0,
    02085                          (PUNICODE_STRING)NULL,
    02086                          0,
    02087                          &disposition
    02088                          );
    02089
    02090     if (!NT_SUCCESS(status)) {
    02091         goto cleanup;
    02092     }
    02093
    02094     //
    02095     // Open the key where the netui code stores information about the cards.
    02096     // During textmode setup this will fail because the Control\Network
    02097     // key is not there. After that it should work, although we may need
    02098     // to create the last node in the path.
    02099     //
    02100
    02101     PiWstrToUnicodeString(&unicodeName, L"Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\{54C7D140-09EF-11D1-B25A-F5FE627ED95E}");
    02102
    02103     InitializeObjectAttributes(&objectAttributes,
    02104                                &unicodeName,
    02105                                OBJ_CASE_INSENSITIVE,
    02106                                currentControlSetHandle,
    02107                                (PSECURITY_DESCRIPTOR)NULL
    02108                                );
    02109
    02110     status = ZwCreateKey(&instanceHandle,
    02111                          KEY_ALL_ACCESS,
    02112                          &objectAttributes,
    02113                          0,
    02114                          (PUNICODE_STRING)NULL,
    02115                          0,
    02116                          &disposition
    02117                          );
    02118
    02119     if (NT_SUCCESS(status)) {
    02120
    02121         //
    02122         // If the PnpInstanceID of the first netboot card matches the one
    02123         // for this device node, and the NET_CARD_INFO that the loader
    02124         // found is the same as the one we saved, then this is the same
    02125         // card with the same instance ID as before, so we don't need to
    02126         // do anything.
    02127         //
    02128
    02129         PiWstrToUnicodeString(&unicodeName, L"PnPInstanceID");
    02130         keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)dataBuffer;
    02131         RtlZeroMemory(dataBuffer, sizeof(dataBuffer));
    02132
    02133         status = ZwQueryValueKey(
    02134                      instanceHandle,
    02135                      &unicodeName,
    02136                      KeyValuePartialInformation,
    02137                      keyValue,
    02138                      sizeof(dataBuffer),
    02139                      &length);
    02140
    02141         //
    02142         // Check that it matches. We can init the string because we zeroed
    02143         // the dataBuffer before reading the key, so even if the
    02144         // registry value had no NULL at the end that is OK.
    02145         //
    02146
    02147         if ((NT_SUCCESS(status)) &&
    02148             (keyValue->Type == REG_SZ)) {
    02149
    02150             RtlInitUnicodeString(&pnpInstanceId, (PWSTR)(keyValue->Data));
    02151
    02152             if (RtlEqualUnicodeString(UnicodeDeviceInstance, &pnpInstanceId, TRUE)) {
    02153
    02154                 //
    02155                 // Instance ID matched, see if the NET_CARD_INFO matches.
    02156                 //
    02157
    02158                 PiWstrToUnicodeString(&unicodeName, L"NetCardInfo");
    02159                 RtlZeroMemory(dataBuffer, sizeof(dataBuffer));
    02160
    02161                 status = ZwQueryValueKey(
    02162                              remoteBootHandle,
    02163                              &unicodeName,
    02164                              KeyValuePartialInformation,
    02165                              keyValue,
    02166                              sizeof(dataBuffer),
    02167                              &length);
    02168
    02169                 if ((NT_SUCCESS(status)) &&
    02170                     (keyValue->Type == REG_BINARY) &&
    02171                     (keyValue->DataLength == sizeof(NET_CARD_INFO)) &&
    02172                     (memcmp(keyValue->Data, setupLoaderBlock->NetbootCardInfo, sizeof(NET_CARD_INFO)) == 0)) {
    02173
    02174                     //
    02175                     // Everything matched, so no need to do any setup.
    02176                     //
    02177
    02178                     status = STATUS_SUCCESS;
    02179                     goto cleanup;
    02180
    02181                 }
    02182             }
    02183         }
    02184     }
    02185
    02186
    02187     //
    02188     // We come through here if the saved registry data was missing or
    02189     // not correct. Write all the relevant values to the registry.
    02190     //
    02191
    02192
    02193     //
    02194     // Service name is in the loader block.
    02195     //
    02196
    02197     PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_SERVICE);
    02198     ZwSetValueKey(UniqueIdHandle,
    02199                   &unicodeName,
    02200                   TITLE_INDEX_VALUE,
    02201                   REG_SZ,
    02202                   setupLoaderBlock->NetbootCardServiceName,
    02203                   (wcslen(setupLoaderBlock->NetbootCardServiceName) + 1) * sizeof(WCHAR)
    02204                   );
    02205
    02206     //
    02207     // ClassGUID is the known net card GUID.
    02208     //
    02209
    02210     PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_CLASSGUID);
    02211     ZwSetValueKey(UniqueIdHandle,
    02212                   &unicodeName,
    02213                   TITLE_INDEX_VALUE,
    02214                   REG_SZ,
    02215                   L"{4D36E972-E325-11CE-BFC1-08002BE10318}",
    02216                   sizeof(L"{4D36E972-E325-11CE-BFC1-08002BE10318}")
    02217                   );
    02218
    02219     //
    02220     // Driver is the first net card.
    02221     //
    02222
    02223     PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_DRIVER);
    02224     ZwSetValueKey(UniqueIdHandle,
    02225                   &unicodeName,
    02226                   TITLE_INDEX_VALUE,
    02227                   REG_SZ,
    02228                   L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000",
    02229                   sizeof(L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000")
    02230                   );
    02231
    02232 #ifdef REMOTE_BOOT
    02233     //
    02234     // Identify this as the netboot card so the network class
    02235     // installer knows to assign the reserved GUID.
    02236     //
    02237
    02238     PiWstrToUnicodeString(&unicodeName, REGSTR_VALUE_CONFIG_FLAGS);
    02239
    02240     keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)dataBuffer;
    02241     RtlZeroMemory(dataBuffer, sizeof(dataBuffer));
    02242
    02243     status = ZwQueryValueKey(UniqueIdHandle,
    02244                              &unicodeName,
    02245                              KeyValuePartialInformation,
    02246                              keyValue,
    02247                              sizeof(dataBuffer),
    02248                              &length);
    02249
    02250     if ((NT_SUCCESS(status)) &&
    02251         (keyValue->Type == REG_DWORD)) {
    02252         //
    02253         // The ConfigFlags value exists in the registry
    02254         //
    02255         tmpValue = (*(PULONG)keyValue->Data) | CONFIGFLAG_NETBOOT_CARD;
    02256     } else {
    02257         tmpValue = CONFIGFLAG_NETBOOT_CARD;
    02258     }
    02259
    02260     ZwSetValueKey(UniqueIdHandle,
    02261                   &unicodeName,
    02262                   TITLE_INDEX_VALUE,
    02263                   REG_DWORD,
    02264                   &tmpValue,
    02265                   sizeof(tmpValue)
    02266                   );
    02267 #endif
    02268
    02269
    02270     //
    02271     // Open a handle for card parameters. We write RemoteBootCard plus
    02272     // whatever the BINL server told us to write.
    02273     //
    02274
    02275     status = IopOpenRegistryKey(&tmpHandle,
    02276                                 NULL,
    02277                                 &CmRegistryMachineSystemCurrentControlSetControlClass,
    02278                                 KEY_ALL_ACCESS,
    02279                                 FALSE
    02280                                 );
    02281
    02282     if (!NT_SUCCESS(status)) {
    02283         goto cleanup;
    02284     }
    02285
    02286     PiWstrToUnicodeString(&unicodeName, L"{4D36E972-E325-11CE-BFC1-08002BE10318}\\0000");
    02287
    02288     status = IopOpenRegistryKey(&parametersHandle,
    02289                                 tmpHandle,
    02290                                 &unicodeName,
    02291                                 KEY_ALL_ACCESS,
    02292                                 FALSE
    02293                                 );
    02294
    02295     ZwClose(tmpHandle);
    02296
    02297     if (!NT_SUCCESS(status)) {
    02298         goto cleanup;
    02299     }
    02300
    02301     //
    02302     // We know that this is a different NIC, so remove all the old parameters.
    02303     //
    02304
    02305     keyValueBasic = (PKEY_VALUE_BASIC_INFORMATION)dataBuffer;
    02306     enumerateIndex = 0;
    02307
    02308     while (TRUE) {
    02309
    02310         RtlZeroMemory(dataBuffer, sizeof(dataBuffer));
    02311
    02312         status = ZwEnumerateValueKey(
    02313                     parametersHandle,
    02314                     enumerateIndex,
    02315                     KeyValueBasicInformation,
    02316                     keyValueBasic,
    02317                     sizeof(dataBuffer),
    02318                     &length
    02319                     );
    02320         if (status == STATUS_NO_MORE_ENTRIES) {
    02321             status = STATUS_SUCCESS;
    02322             break;
    02323         }
    02324
    02325         if (!NT_SUCCESS(status)) {
    02326             goto cleanup;
    02327         }
    02328
    02329         //
    02330         // We don't delete "NetCfgInstanceID", it won't change and
    02331         // its presence signifies to the net class installer that
    02332         // this is a replacement not a clean install.
    02333         //
    02334
    02335         if (_wcsicmp(keyValueBasic->Name, L"NetCfgInstanceID") != 0) {
    02336
    02337             RtlInitUnicodeString(&keyName, keyValueBasic->Name);
    02338             status = ZwDeleteValueKey(
    02339                         parametersHandle,
    02340                         &keyName
    02341                         );
    02342
    02343             if (!NT_SUCCESS(status)) {
    02344                 goto cleanup;
    02345             }
    02346
    02347         } else {
    02348
    02349             enumerateIndex = 1;   // leave NetCfgInstanceID at index 0
    02350         }
    02351
    02352     }
    02353
    02354     //
    02355     // Write a parameter called RemoteBootCard set to TRUE, this
    02356     // is primarily so NDIS can recognize this as such.
    02357     //
    02358
    02359     PiWstrToUnicodeString(&unicodeName, L"RemoteBootCard");
    02360     tmpValue = 1;
    02361     ZwSetValueKey(parametersHandle,
    02362                   &unicodeName,
    02363                   TITLE_INDEX_VALUE,
    02364                   REG_DWORD,
    02365                   &tmpValue,
    02366                   sizeof(tmpValue)
    02367                   );
    02368
    02369
    02370     //
    02371     // Store any other parameters sent from the server.
    02372     //
    02373
    02374     registryList = setupLoaderBlock->NetbootCardRegistry;
    02375
    02376     if (registryList != NULL) {
    02377
    02378         STRING aString;
    02379         UNICODE_STRING uString, uString2;
    02380
    02381         //
    02382         // The registry list is a series of name\0type\0value\0, with
    02383         // a final \0 at the end. It is in ANSI, not UNICODE.
    02384         //
    02385         // All values are stored under parametersHandle. Type is 1 for
    02386         // DWORD and 2 for SZ.
    02387         //
    02388
    02389         uString.Buffer = tempNameBuffer;
    02390         uString.MaximumLength = sizeof(tempNameBuffer);
    02391
    02392         while (*registryList != '\0') {
    02393
    02394             //
    02395             // First the name.
    02396             //
    02397
    02398             RtlInitString(&aString, registryList);
    02399             RtlAnsiStringToUnicodeString(&uString, &aString, FALSE);
    02400
    02401             //
    02402             // Now the type.
    02403             //
    02404
    02405             registryList += (strlen(registryList) + 1);
    02406
    02407             if (*registryList == '1') {
    02408
    02409                 //
    02410                 // A DWORD, parse it.
    02411                 //
    02412
    02413                 registryList += 2;   // skip "1\0"
    02414                 tmpValue = 0;
    02415
    02416                 while (*registryList != '\0') {
    02417                     tmpValue = (tmpValue * 10) + (*registryList - '0');
    02418                     ++registryList;
    02419                 }
    02420
    02421                 ZwSetValueKey(parametersHandle,
    02422                               &uString,
    02423                               TITLE_INDEX_VALUE,
    02424                               REG_DWORD,
    02425                               &tmpValue,
    02426                               sizeof(tmpValue)
    02427                               );
    02428
    02429                 registryList += (strlen(registryList) + 1);
    02430
    02431             } else if (*registryList == '2') {
    02432
    02433                 //
    02434                 // An SZ, convert to Unicode.
    02435                 //
    02436
    02437                 registryList += 2;   // skip "2\0"
    02438
    02439                 uString2.Buffer = tempValueBuffer;
    02440                 uString2.MaximumLength = sizeof(tempValueBuffer);
    02441                 RtlInitAnsiString(&aString, registryList);
    02442                 RtlAnsiStringToUnicodeString(&uString2, &aString, FALSE);
    02443
    02444                 ZwSetValueKey(parametersHandle,
    02445                               &uString,
    02446                               TITLE_INDEX_VALUE,
    02447                               REG_SZ,
    02448                               uString2.Buffer,
    02449                               uString2.Length + sizeof(WCHAR)
    02450                               );
    02451
    02452                 registryList += (strlen(registryList) + 1);
    02453
    02454             } else {
    02455
    02456                 //
    02457                 // Not "1" or "2", so stop processing registryList.
    02458                 //
    02459
    02460                 break;
    02461
    02462             }
    02463
    02464         }
    02465
    02466     }
    02467
    02468     //
    02469     // Save the NET_CARD_INFO so we can check it next time.
    02470     //
    02471
    02472     PiWstrToUnicodeString(&unicodeName, L"NetCardInfo");
    02473
    02474     ZwSetValueKey(remoteBootHandle,
    02475                   &unicodeName,
    02476                   TITLE_INDEX_VALUE,
    02477                   REG_BINARY,
    02478                   setupLoaderBlock->NetbootCardInfo,
    02479                   sizeof(NET_CARD_INFO)
    02480                   );
    02481
    02482
    02483     //
    02484     // Save the hardware ID, driver name, and service name,
    02485     // so the loader can read  those if the server is down
    02486     // on subsequent boots.
    02487     //
    02488
    02489     PiWstrToUnicodeString(&unicodeName, L"HardwareId");
    02490
    02491     ZwSetValueKey(remoteBootHandle,
    02492                   &unicodeName,
    02493                   TITLE_INDEX_VALUE,
    02494                   REG_SZ,
    02495                   setupLoaderBlock->NetbootCardHardwareId,
    02496                   (wcslen(setupLoaderBlock->NetbootCardHardwareId) + 1) * sizeof(WCHAR)
    02497                   );
    02498
    02499     PiWstrToUnicodeString(&unicodeName, L"DriverName");
    02500
    02501     ZwSetValueKey(remoteBootHandle,
    02502                   &unicodeName,
    02503                   TITLE_INDEX_VALUE,
    02504                   REG_SZ,
    02505                   setupLoaderBlock->NetbootCardDriverName,
    02506                   (wcslen(setupLoaderBlock->NetbootCardDriverName) + 1) * sizeof(WCHAR)
    02507                   );
    02508
    02509     PiWstrToUnicodeString(&unicodeName, L"ServiceName");
    02510
    02511     ZwSetValueKey(remoteBootHandle,
    02512                   &unicodeName,
    02513                   TITLE_INDEX_VALUE,
    02514                   REG_SZ,
    02515                   setupLoaderBlock->NetbootCardServiceName,
    02516                   (wcslen(setupLoaderBlock->NetbootCardServiceName) + 1) * sizeof(WCHAR)
    02517                   );
    02518
    02519     //
    02520     // Save the device instance, in case we need to ID the card later.
    02521     //
    02522
    02523     PiWstrToUnicodeString(&unicodeName, L"DeviceInstance");
    02524
    02525     ZwSetValueKey(remoteBootHandle,
    02526                   &unicodeName,
    02527                   TITLE_INDEX_VALUE,
    02528                   REG_SZ,
    02529                   UnicodeDeviceInstance->Buffer,
    02530                   UnicodeDeviceInstance->Length + sizeof(WCHAR)
    02531                   );
    02532
    02533     //
    02534     // Make sure we only pick one card to setup this way!
    02535     //
    02536
    02537     IopRemoteBootCardInitialized = TRUE;
    02538
    02539
    02540 cleanup:
    02541     if (instanceHandle != NULL) {
    02542         ZwClose(instanceHandle);
    02543     }
    02544     if (remoteBootHandle != NULL) {
    02545         ZwClose(remoteBootHandle);
    02546     }
    02547     if (parametersHandle != NULL) {
    02548         ZwClose(parametersHandle);
    02549     }
    02550     if (currentControlSetHandle != NULL) {
    02551         ZwClose(currentControlSetHandle);
    02552     }
    02553
    02554     return status;
    02555
    02556 }

VOID IopStartApcHardError | ( | IN PVOID | StartContext | ) |

Definition at line 6870 of file internal.c.

References ExFreePool(), IO_DISK_INCREMENT, IoCompleteRequest, IopApcHardError(), Irp, NT_SUCCESS, NTSTATUS(), NULL, and PsCreateSystemThread().

Referenced by IoRaiseHardError().

    06876                    :
    06877
    06878     This function is invoked in an ExWorker thread when we need to do a
    06879     hard error pop-up, but the Irp's originating thread is at APC level,
    06880     ie. IoPageRead.  It starts a thread to hold the pop-up.
    06881
    06882 Arguments:
    06883
    06884     StartContext - Startup context, contains a IOP_APC_HARD_ERROR_PACKET.
    06885
    06886 Return Value:
    06887
    06888     None.
    06889
    06890 --*/
    06891
    06892 {
    06893     HANDLE thread;
    06894     NTSTATUS status;
    06895
    06896     //
    06897     //  Create the hard error pop-up thread.  If for whatever reason we
    06898     //  can't do this then just complete the Irp with the error.
    06899     //
    06900
    06901     status = PsCreateSystemThread( &thread,
    06902                                    0,
    06903                                    (POBJECT_ATTRIBUTES)NULL,
    06904                                    (HANDLE)0,
    06905                                    (PCLIENT_ID)NULL,
    06906                                    IopApcHardError,
    06907                                    StartContext );
    06908
    06909     if ( !NT_SUCCESS( status ) ) {
    06910
    06911
    06912         IoCompleteRequest( ((PIOP_APC_HARD_ERROR_PACKET)StartContext)->Irp,
    06913                            IO_DISK_INCREMENT );
    06914         ExFreePool( StartContext );
    06915         return;
    06916     }
    06917
    06918     //
    06919     //  Close thread handle
    06920     //
    06921
    06922     ZwClose(thread);
    06923 }

NTSTATUS IopStartNetworkForRemoteBoot | ( | PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 770 of file netboot.c.

References ASSERT, _SETUP_LOADER_BLOCK::DefaultRouter, ExAllocatePoolWithTag, ExFreePool(), FALSE, _SETUP_LOADER_BLOCK::Flags, IoGetCurrentProcess(), IopAssignNetworkDriveLetter(), IopCacheNetbiosNameForIpAddress(), IopSetDefaultGateway(), KeDelayExecutionThread(), KernelMode, L, max, MAX_PATH, _SETUP_LOADER_BLOCK::NetbootCardDriverName, _SETUP_LOADER_BLOCK::NetBootSecret, NonPagedPool, NT_SUCCESS, NtClose(), NtCreateFile(), NtDeviceIoControlFile(), NtFsControlFile(), NtOpenKey(), NtQueryValueKey(), NTSTATUS(), NULL, _EPROCESS::Pcb, RtlCreateUnicodeString(), RtlFreeUnicodeString(), RtlInitUnicodeString(), SETUPBLK_FLAGS_IS_TEXTMODE, _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, and TRUE.

Referenced by IoInitSystem().

    00773 {
    00774     NTSTATUS status;
    00775     HANDLE dgHandle;
    00776     HANDLE keyHandle;
    00777     OBJECT_ATTRIBUTES objectAttributes;
    00778     IO_STATUS_BLOCK ioStatusBlock;
    00779     UNICODE_STRING string;
    00780     UNICODE_STRING computerName;
    00781     UNICODE_STRING domainName;
    00782     PUCHAR buffer;
    00783     ULONG bufferLength;
    00784     PLMR_REQUEST_PACKET rrp;
    00785     PLMDR_REQUEST_PACKET drrp;
    00786     WKSTA_INFO_502 wkstaConfig;
    00787     WKSTA_TRANSPORT_INFO_0 wkstaTransportInfo;
    00788     LARGE_INTEGER interval;
    00789     ULONG length;
    00790     PKEY_VALUE_PARTIAL_INFORMATION keyValue;
    00791     BOOLEAN startDatagramReceiver;
    00792     ULONG enumerateAttempts;
    00793 #if defined(REMOTE_BOOT)
    00794     PWSTR NetHDCSCPartition;
    00795     BOOLEAN leaveRdrHandleOpen;
    00796     BOOLEAN pinNetDriver;
    00797 #else
    00798     HANDLE RdrHandle;
    00799 #endif // defined(REMOTE_BOOT)
    00800
    00801     //
    00802     // Initialize for cleanup.
    00803     //
    00804
    00805     buffer = NULL;
    00806     computerName.Buffer = NULL;
    00807     domainName.Buffer = NULL;
    00808     dgHandle = NULL;
    00809     RdrHandle = NULL;
    00810 #if defined(REMOTE_BOOT)
    00811     NetHDCSCPartition = NULL;
    00812     leaveRdrHandleOpen = FALSE;
    00813     pinNetDriver = FALSE;
    00814 #endif // defined(REMOTE_BOOT)
    00815
    00816     //
    00817     // Allocate a temporary buffer. It has to be big enough for all the
    00818     // various FSCTLs we send down.
    00819     //
    00820
    00821     bufferLength = max(sizeof(LMR_REQUEST_PACKET) + (MAX_PATH + 1) * sizeof(WCHAR) +
    00822                                                  (DNLEN + 1) * sizeof(WCHAR),
    00823                        max(sizeof(LMDR_REQUEST_PACKET),
    00824                            FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + MAX_PATH));
    00825     bufferLength = max(bufferLength, sizeof(LMMR_RI_INITIALIZE_SECRET));
    00826
    00827 #if defined(REMOTE_BOOT)
    00828     NetHDCSCPartition = ExAllocatePoolWithTag(
    00829                             NonPagedPool,
    00830                             (80 * sizeof(WCHAR)) + bufferLength,
    00831                             'bRoI'
    00832                             );
    00833     if (NetHDCSCPartition == NULL) {
    00834         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to allocate buffer\n"));
    00835         status = STATUS_INSUFFICIENT_RESOURCES;
    00836         goto cleanup;
    00837     }
    00838     buffer = (PUCHAR)(NetHDCSCPartition + 80);
    00839 #else
    00840     buffer = ExAllocatePoolWithTag( NonPagedPool, bufferLength, 'bRoI' );
    00841     if (buffer == NULL) {
    00842         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to allocate buffer\n"));
    00843         status = STATUS_INSUFFICIENT_RESOURCES;
    00844         goto cleanup;
    00845     }
    00846 #endif // defined(REMOTE_BOOT)
    00847
    00848     rrp = (PLMR_REQUEST_PACKET)buffer;
    00849     drrp = (PLMDR_REQUEST_PACKET)buffer;
    00850
    00851     //
    00852     // Open the redirector and the datagram receiver.
    00853     //
    00854
    00855     RtlInitUnicodeString( &string, L"\\Device\\LanmanRedirector" );
    00856
    00857     InitializeObjectAttributes(
    00858         &objectAttributes,
    00859         &string,
    00860         OBJ_CASE_INSENSITIVE,
    00861         NULL,
    00862         NULL
    00863         );
    00864
    00865     status = NtCreateFile(
    00866                 &RdrHandle,
    00867                 GENERIC_READ | GENERIC_WRITE,
    00868                 &objectAttributes,
    00869                 &ioStatusBlock,
    00870                 NULL,
    00871                 0,
    00872                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    00873                 FILE_OPEN,
    00874                 FILE_SYNCHRONOUS_IO_NONALERT,
    00875                 NULL,
    00876                 0
    00877                 );
    00878     if ( !NT_SUCCESS(status) ) {
    00879         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to open redirector: %x\n", status ));
    00880         goto cleanup;
    00881     }
    00882
    00883 #if defined(REMOTE_BOOT)
    00884     RdrHandleProcess = &IoGetCurrentProcess()->Pcb;
    00885 #endif // defined(REMOTE_BOOT)
    00886
    00887     RtlInitUnicodeString( &string, DD_BROWSER_DEVICE_NAME_U );
    00888
    00889     InitializeObjectAttributes(
    00890         &objectAttributes,
    00891         &string,
    00892         OBJ_CASE_INSENSITIVE,
    00893         NULL,
    00894         NULL
    00895         );
    00896
    00897     status = NtCreateFile(
    00898                 &dgHandle,
    00899                 GENERIC_READ | GENERIC_WRITE,
    00900                 &objectAttributes,
    00901                 &ioStatusBlock,
    00902                 NULL,
    00903                 0,
    00904                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    00905                 FILE_OPEN,
    00906                 FILE_SYNCHRONOUS_IO_NONALERT,
    00907                 NULL,
    00908                 0
    00909                 );
    00910     if ( !NT_SUCCESS(status) ) {
    00911         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to open datagram receiver: %x\n", status ));
    00912         goto cleanup;
    00913     }
    00914
    00915     //
    00916     // If the setup loader block has a disk secret in it provided by the
    00917     // loader, pass this down to the redirector (do this before sending
    00918     // the LMR_START, since that uses this information).
    00919     //
    00920
    00921 #if defined(REMOTE_BOOT)
    00922     if (LoaderBlock->SetupLoaderBlock->NetBootSecret)
    00923 #endif // defined(REMOTE_BOOT)
    00924     {
    00925         PLMMR_RI_INITIALIZE_SECRET RbInit = (PLMMR_RI_INITIALIZE_SECRET)buffer;
    00926
    00927         ASSERT(LoaderBlock->SetupLoaderBlock->NetBootSecret != NULL);
    00928         RtlCopyMemory(
    00929             &RbInit->Secret,
    00930             LoaderBlock->SetupLoaderBlock->NetBootSecret,
    00931             sizeof(RI_SECRET));
    00932 #if defined(REMOTE_BOOT)
    00933         RbInit->UsePassword2 = LoaderBlock->SetupLoaderBlock->NetBootUsePassword2;
    00934 #endif // defined(REMOTE_BOOT)
    00935
    00936         status = NtFsControlFile(
    00937                     RdrHandle,
    00938                     NULL,
    00939                     NULL,
    00940                     NULL,
    00941                     &ioStatusBlock,
    00942                     FSCTL_LMMR_RI_INITIALIZE_SECRET,
    00943                     buffer,
    00944                     sizeof(LMMR_RI_INITIALIZE_SECRET),
    00945                     NULL,
    00946                     0
    00947                     );
    00948
    00949         if ( NT_SUCCESS(status) ) {
    00950             status = ioStatusBlock.Status;
    00951         }
    00952         if ( !NT_SUCCESS(status) ) {
    00953             KdPrint(( "IopStartNetworkForRemoteBoot: Unable to FSCTL(RB initialize) redirector: %x\n", status ));
    00954             goto cleanup;
    00955         }
    00956     }
    00957
    00958     //
    00959     // Read the computer name and domain name from the registry so we
    00960     // can give them to the datagram receiver. During textmode setup
    00961     // the domain name will not be there, so we won't start the datagram
    00962     // receiver, which is fine.
    00963     //
    00964     // BUGBUG: Figure out the correct location to read the domain name
    00965     // from -- this one is a special hack in winnt.sif just for this.
    00966     //
    00967
    00968     RtlInitUnicodeString( &string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ComputerName" );
    00969
    00970     InitializeObjectAttributes(
    00971         &objectAttributes,
    00972         &string,
    00973         OBJ_CASE_INSENSITIVE,
    00974         NULL,
    00975         NULL
    00976         );
    00977
    00978     status = NtOpenKey( &keyHandle, KEY_ALL_ACCESS, &objectAttributes );
    00979     if ( !NT_SUCCESS(status) ) {
    00980         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to open ComputerName key: %x\n", status ));
    00981         goto cleanup;
    00982     }
    00983
    00984     RtlInitUnicodeString( &string, L"ComputerName" );
    00985
    00986     keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
    00987     RtlZeroMemory(buffer, bufferLength);
    00988
    00989     status = NtQueryValueKey(
    00990                  keyHandle,
    00991                  &string,
    00992                  KeyValuePartialInformation,
    00993                  keyValue,
    00994                  bufferLength,
    00995                  &length);
    00996
    00997     NtClose( keyHandle );
    00998     if ( !NT_SUCCESS(status) ) {
    00999         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to query ComputerName value: %x\n", status ));
    01000         goto cleanup;
    01001     }
    01002
    01003     if ( !RtlCreateUnicodeString(&computerName, (PWSTR)keyValue->Data) ) {
    01004         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to create ComputerName string\n" ));
    01005         status = STATUS_INSUFFICIENT_RESOURCES;
    01006         goto cleanup;
    01007     }
    01008
    01009     domainName.Length = 0;
    01010
    01011     RtlInitUnicodeString( &string, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\DomainName" );
    01012
    01013     InitializeObjectAttributes(
    01014         &objectAttributes,
    01015         &string,
    01016         OBJ_CASE_INSENSITIVE,
    01017         NULL,
    01018         NULL
    01019         );
    01020
    01021     status = NtOpenKey( &keyHandle, KEY_ALL_ACCESS, &objectAttributes );
    01022     if ( !NT_SUCCESS(status) ) {
    01023         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to open DomainName key: %x\n", status ));
    01024         startDatagramReceiver = FALSE;
    01025     } else {
    01026
    01027         RtlInitUnicodeString( &string, L"DomainName" );
    01028
    01029         keyValue = (PKEY_VALUE_PARTIAL_INFORMATION)buffer;
    01030         RtlZeroMemory(buffer, bufferLength);
    01031
    01032         status = NtQueryValueKey(
    01033                      keyHandle,
    01034                      &string,
    01035                      KeyValuePartialInformation,
    01036                      keyValue,
    01037                      bufferLength,
    01038                      &length);
    01039
    01040         NtClose( keyHandle );
    01041         if ( !NT_SUCCESS(status) ) {
    01042             KdPrint(( "IopStartNetworkForRemoteBoot: Unable to query Domain value: %x\n", status ));
    01043             startDatagramReceiver = FALSE;
    01044         } else {
    01045             if ( !RtlCreateUnicodeString(&domainName, (PWSTR)keyValue->Data) ) {
    01046                 KdPrint(( "IopStartNetworkForRemoteBoot: Unable to create DomainName string\n" ));
    01047                 status = STATUS_INSUFFICIENT_RESOURCES;
    01048                 goto cleanup;
    01049             }
    01050             startDatagramReceiver = TRUE;
    01051         }
    01052     }
    01053
    01054     //
    01055     // Tell the redir to start.
    01056     //
    01057
    01058     rrp->Type = ConfigInformation;
    01059     rrp->Version = REQUEST_PACKET_VERSION;
    01060
    01061     rrp->Parameters.Start.RedirectorNameLength = computerName.Length;
    01062     RtlCopyMemory(rrp->Parameters.Start.RedirectorName,
    01063                   computerName.Buffer,
    01064                   computerName.Length);
    01065
    01066     rrp->Parameters.Start.DomainNameLength = domainName.Length;
    01067     RtlCopyMemory(((PUCHAR)rrp->Parameters.Start.RedirectorName) + computerName.Length,
    01068                   domainName.Buffer,
    01069                   domainName.Length);
    01070
    01071     RtlFreeUnicodeString(&computerName);
    01072     RtlFreeUnicodeString(&domainName);
    01073
    01074     wkstaConfig.wki502_char_wait = 3600;
    01075     wkstaConfig.wki502_maximum_collection_count = 16;
    01076     wkstaConfig.wki502_collection_time = 250;
    01077     wkstaConfig.wki502_keep_conn = 600;
    01078     wkstaConfig.wki502_max_cmds = 5;
    01079     wkstaConfig.wki502_sess_timeout = 45;
    01080     wkstaConfig.wki502_siz_char_buf = 512;
    01081     wkstaConfig.wki502_max_threads = 17;
    01082     wkstaConfig.wki502_lock_quota = 6144;
    01083     wkstaConfig.wki502_lock_increment = 10;
    01084     wkstaConfig.wki502_lock_maximum = 500;
    01085     wkstaConfig.wki502_pipe_increment = 10;
    01086     wkstaConfig.wki502_pipe_maximum = 500;
    01087     wkstaConfig.wki502_cache_file_timeout = 40;
    01088     wkstaConfig.wki502_dormant_file_limit = 45;
    01089     wkstaConfig.wki502_read_ahead_throughput = MAXULONG;
    01090     wkstaConfig.wki502_num_mailslot_buffers = 3;
    01091     wkstaConfig.wki502_num_srv_announce_buffers = 20;
    01092     wkstaConfig.wki502_max_illegal_datagram_events = 5;
    01093     wkstaConfig.wki502_illegal_datagram_event_reset_frequency = 60;
    01094     wkstaConfig.wki502_log_election_packets = FALSE;
    01095     wkstaConfig.wki502_use_opportunistic_locking = TRUE;
    01096     wkstaConfig.wki502_use_unlock_behind = TRUE;
    01097     wkstaConfig.wki502_use_close_behind = TRUE;
    01098     wkstaConfig.wki502_buf_named_pipes = TRUE;
    01099     wkstaConfig.wki502_use_lock_read_unlock = TRUE;
    01100     wkstaConfig.wki502_utilize_nt_caching = TRUE;
    01101     wkstaConfig.wki502_use_raw_read = TRUE;
    01102     wkstaConfig.wki502_use_raw_write = TRUE;
    01103     wkstaConfig.wki502_use_write_raw_data = TRUE;
    01104     wkstaConfig.wki502_use_encryption = TRUE;
    01105     wkstaConfig.wki502_buf_files_deny_write = TRUE;
    01106     wkstaConfig.wki502_buf_read_only_files = TRUE;
    01107     wkstaConfig.wki502_force_core_create_mode = TRUE;
    01108     wkstaConfig.wki502_use_512_byte_max_transfer = FALSE;
    01109
    01110     status = NtFsControlFile(
    01111                 RdrHandle,
    01112                 NULL,
    01113                 NULL,
    01114                 NULL,
    01115                 &ioStatusBlock,
    01116                 FSCTL_LMR_START | 0x80000000,
    01117                 rrp,
    01118                 sizeof(LMR_REQUEST_PACKET) +
    01119                     rrp->Parameters.Start.RedirectorNameLength +
    01120                     rrp->Parameters.Start.DomainNameLength,
    01121                 &wkstaConfig,
    01122                 sizeof(wkstaConfig)
    01123                 );
    01124
    01125     if ( NT_SUCCESS(status) ) {
    01126         status = ioStatusBlock.Status;
    01127     }
    01128     if ( !NT_SUCCESS(status) ) {
    01129         KdPrint(( "IopStartNetworkForRemoteBoot: Unable to FSCTL(start) redirector: %x\n", status ));
    01130         goto cleanup;
    01131     }
    01132
    01133     if (startDatagramReceiver) {
    01134
    01135         //
    01136         // Tell the datagram receiver to start.
    01137         //
    01138
    01139         drrp->Version = LMDR_REQUEST_PACKET_VERSION;
    01140
    01141         drrp->Parameters.Start.NumberOfMailslotBuffers = 16;
    01142         drrp->Parameters.Start.NumberOfServerAnnounceBuffers = 20;
    01143         drrp->Parameters.Start.IllegalDatagramThreshold = 5;
    01144         drrp->Parameters.Start.EventLogResetFrequency = 60;
    01145         drrp->Parameters.Start.LogElectionPackets = FALSE;
    01146
    01147         drrp->Parameters.Start.IsLanManNt = FALSE;
    01148
    01149         status = NtDeviceIoControlFile(
    01150                     dgHandle,
    01151                     NULL,
    01152                     NULL,
    01153                     NULL,
    01154                     &ioStatusBlock,
    01155                     IOCTL_LMDR_START,
    01156                     drrp,
    01157                     sizeof(LMDR_REQUEST_PACKET),
    01158                     NULL,
    01159                     0
    01160                     );
    01161
    01162         if ( NT_SUCCESS(status) ) {
    01163             status = ioStatusBlock.Status;
    01164         }
    01165
    01166         NtClose( dgHandle );
    01167         dgHandle = NULL;
    01168
    01169         if ( !NT_SUCCESS(status) ) {
    01170             KdPrint(( "IopStartNetworkForRemoteBoot: Unable to IOCTL(start) datagram receiver: %x\n", status ));
    01171             goto cleanup;
    01172         }
    01173
    01174     } else {
    01175
    01176         NtClose( dgHandle );
    01177         dgHandle = NULL;
    01178
    01179         //
    01180         // Tell the redir to bind to the transports.
    01181         //
    01182         // Note: In the current redirector implementation, this call just
    01183         // tells the redirector to register for TDI PnP notifications.
    01184         // Starting the datagram receiver also does this, so we only issue
    01185         // this FSCTL if we're not starting the datagram receiver.
    01186         //
    01187
    01188         status = NtFsControlFile(
    01189                     RdrHandle,
    01190                     NULL,
    01191                     NULL,
    01192                     NULL,
    01193                     &ioStatusBlock,
    01194                     FSCTL_LMR_BIND_TO_TRANSPORT | 0x80000000,
    01195                     NULL,
    01196                     0,
    01197                     NULL,
    01198                     0
    01199                     );
    01200
    01201         if ( NT_SUCCESS(status) ) {
    01202             status = ioStatusBlock.Status;
    01203         }
    01204
    01205         if ( !NT_SUCCESS(status) ) {
    01206             KdPrint(( "IopStartNetworkForRemoteBoot: Unable to FSCTL(bind) redirector: %x\n", status ));
    01207             goto cleanup;
    01208         }
    01209     }
    01210
    01211 #if defined(REMOTE_BOOT)
    01212     if (((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_IS_TEXTMODE) == 0) &&
    01213         ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_FORMAT_NEEDED) == 0)) {
    01214
    01215         //
    01216         // Get the path to the boot partition on the disk for CSC and redirection
    01217         // Note: On failure, this defaults to \Device\Harddisk0\Partition1
    01218         //
    01219
    01220         IopGetHarddiskInfo(NetHDCSCPartition);
    01221
    01222         //
    01223         // Tell the redirector to initialize remote boot redirection (back
    01224         // to the local disk). Note that we only do this if we're NOT doing
    01225         // textmode setup. During textmode, we let Setup do this so that it
    01226         // can do so AFTER it has reformatted the local disk.
    01227         //
    01228
    01229         status = NtFsControlFile(
    01230                     RdrHandle,
    01231                     NULL,
    01232                     NULL,
    01233                     NULL,
    01234                     &ioStatusBlock,
    01235                     FSCTL_LMR_START_RBR,
    01236                     NetHDCSCPartition,
    01237                     wcslen(NetHDCSCPartition) * sizeof(WCHAR),
    01238                     NULL,
    01239                     0
    01240                     );
    01241
    01242         if (NT_SUCCESS(status) ) {
    01243             status = ioStatusBlock.Status;
    01244         }
    01245
    01246         if ( !NT_SUCCESS(status) ) {
    01247             KdPrint(( "IopStartNetworkForRemoteBoot: Unable to FSCTL(RBR) redirector: %x\n", status ));
    01248         }
    01249     }
    01250
    01251     if ( (LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_DISCONNECTED) == 0 )
    01252 #endif // defined(REMOTE_BOOT)
    01253     {
    01254
    01255         //
    01256         // Loop until the redirector is bound to the transport. It may take a
    01257         // while because TDI defers notification of binding to a worker thread.
    01258         // We start with a half a second wait and double it each time, trying
    01259         // five times total.
    01260         //
    01261
    01262         interval.QuadPart = -500 * 1000 * 10;    // 1/2 second, relative
    01263         enumerateAttempts = 0;
    01264
    01265         while (TRUE) {
    01266
    01267             KeDelayExecutionThread(KernelMode, FALSE, &interval);
    01268
    01269             RtlZeroMemory(rrp, sizeof(LMR_REQUEST_PACKET));
    01270
    01271             rrp->Type = EnumerateTransports;
    01272             rrp->Version = REQUEST_PACKET_VERSION;
    01273
    01274             status = NtFsControlFile(
    01275                         RdrHandle,
    01276                         NULL,
    01277                         NULL,
    01278                         NULL,
    01279                         &ioStatusBlock,
    01280                         FSCTL_LMR_ENUMERATE_TRANSPORTS,
    01281                         rrp,
    01282                         sizeof(LMR_REQUEST_PACKET),
    01283                         &wkstaTransportInfo,
    01284                         sizeof(wkstaTransportInfo)
    01285                         );
    01286
    01287             if ( NT_SUCCESS(status) ) {
    01288                 status = ioStatusBlock.Status;
    01289             }
    01290             if ( !NT_SUCCESS(status) ) {
    01291                 //KdPrint(( "IopStartNetworkForRemoteBoot: Unable to FSCTL(enumerate) redirector: %x\n", status ));
    01292             } else if (rrp->Parameters.Get.TotalBytesNeeded == 0) {
    01293                 //KdPrint(( "IopStartNetworkForRemoteBoot: FSCTL(enumerate) returned 0 entries\n" ));
    01294             } else {
    01295                 break;
    01296             }
    01297
    01298             ++enumerateAttempts;
    01299
    01300             if (enumerateAttempts == 5) {
    01301                 KdPrint(( "IopStartNetworkForRemoteBoot: Redirector didn't start\n" ));
    01302                 status = STATUS_REDIRECTOR_NOT_STARTED;
    01303                 goto cleanup;
    01304             }
    01305
    01306             interval.QuadPart *= 2;
    01307
    01308         }
    01309     }
    01310
    01311     //
    01312     // Prime the transport.
    01313     //
    01314
    01315 #if defined(REMOTE_BOOT)
    01316     IopEnableRemoteBootSecurity(LoaderBlock);
    01317 #endif // defined(REMOTE_BOOT)
    01318     IopSetDefaultGateway(LoaderBlock->SetupLoaderBlock->DefaultRouter);
    01319     IopCacheNetbiosNameForIpAddress(LoaderBlock);
    01320
    01321 #if defined(REMOTE_BOOT)
    01322     //
    01323     // CSC needs to be initialized after binding to the transport because ResetCSC
    01324     // (if needed) will try to enumerate the files and directories on the server.
    01325     //
    01326
    01327     if (((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_IS_TEXTMODE) == 0) &&
    01328         ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_FORMAT_NEEDED) == 0)
    01329 #if 0
    01330         && ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_DISABLE_CSC) != 0)
    01331 #endif
    01332         ) {
    01333
    01334         wcstombs(buffer, NetHDCSCPartition, wcslen(NetHDCSCPartition) + 1);
    01335         strcat(buffer, REMOTE_BOOT_IMIRROR_PATH_A REMOTE_BOOT_CSC_SUBDIR_A);
    01336
    01337         status = IopInitCsc( buffer );
    01338
    01339         //
    01340         //  If we are connected and either we are part way through a reset of
    01341         //  the csc or the init failed then reset the csc.
    01342         //
    01343
    01344         if ( NT_SUCCESS(status) ) {
    01345
    01346             if (StartCsc == FLUSH_CSC ) {
    01347
    01348                 if ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_DISCONNECTED) == 0) {
    01349
    01350                     //
    01351                     // CSC may have lost the pin information.
    01352                     //
    01353
    01354                     status = IopResetCsc( buffer );
    01355
    01356                     if ( !NT_SUCCESS(status) ) {
    01357                         KdPrint(("IopStartNetworkForRemoteBoot: reset of Csc failed %x\n", status));
    01358                     }
    01359                 } else {
    01360                     IoCscInitializationFailed = TRUE;
    01361                 }
    01362             } else if ((LoaderBlock->SetupLoaderBlock->Flags & SETUPBLK_FLAGS_PIN_NET_DRIVER) &&
    01363                        (LoaderBlock->SetupLoaderBlock->NetbootCardDriverName[0] != L'\0')) {
    01364
    01365                 //
    01366                 // if we are connected and we're not repinning all files and
    01367                 // we have a new net card driver to pin, then pin it below
    01368                 // after we've created called IopAssignNetworkDriveLetter
    01369                 //
    01370
    01371                 pinNetDriver = TRUE;
    01372             }
    01373         }
    01374
    01375         if ( !NT_SUCCESS(status) ) {
    01376             KdPrint(("IopStartNetworkForRemoteBoot: initialization of Csc failed %x\n", status));
    01377             IoCscInitializationFailed = TRUE;
    01378             SharedUserData->SystemFlags |= SYSTEM_FLAG_DISKLESS_CLIENT;
    01379         }
    01380
    01381     } else {
    01382         IoCscInitializationFailed = TRUE;
    01383         SharedUserData->SystemFlags |= SYSTEM_FLAG_DISKLESS_CLIENT;
    01384     }
    01385 #endif // defined(REMOTE_BOOT)
    01386
    01387     IopAssignNetworkDriveLetter(LoaderBlock);
    01388
    01389 #if defined(REMOTE_BOOT)
    01390     if (pinNetDriver) {
    01391
    01392         //
    01393         //  Pin the new net card driver simply by opening it.  if it
    01394         //  fails, it's not fatal, as we'll eventually pin it since
    01395         //  the directory it's in is marked as system/inherit.
    01396         //
    01397
    01398         HANDLE driverHandle = NULL;
    01399         PWCHAR fullDriverName;
    01400
    01401         fullDriverName = (PWCHAR) ExAllocatePoolWithTag(
    01402                             NonPagedPool,
    01403                             sizeof( L"\\SystemRoot\\System32\\Drivers\\" ) +
    01404                             sizeof( LoaderBlock->SetupLoaderBlock->NetbootCardDriverName ),
    01405                             'bRoI'
    01406                             );
    01407
    01408         if (fullDriverName != NULL) {
    01409
    01410             wcscpy(fullDriverName, L"\\SystemRoot\\System32\\Drivers\\");
    01411             wcscat(fullDriverName, LoaderBlock->SetupLoaderBlock->NetbootCardDriverName);
    01412
    01413             RtlInitUnicodeString( &string, fullDriverName );
    01414
    01415             InitializeObjectAttributes(
    01416                 &objectAttributes,
    01417                 &string,
    01418                 OBJ_CASE_INSENSITIVE,
    01419                 NULL,
    01420                 NULL
    01421                 );
    01422
    01423             status = NtCreateFile(
    01424                         &driverHandle,
    01425                         GENERIC_READ,
    01426                         &objectAttributes,
    01427                         &ioStatusBlock,
    01428                         NULL,
    01429                         FILE_ATTRIBUTE_NORMAL,
    01430                         FILE_SHARE_READ,
    01431                         FILE_OPEN,
    01432                         FILE_SYNCHRONOUS_IO_NONALERT,
    01433                         NULL,
    01434                         0
    01435                         );
    01436             if ( !NT_SUCCESS(status) ) {
    01437
    01438                 //
    01439                 //  this is not a fatal error, the redir should pin it eventually
    01440                 //
    01441
    01442                 KdPrint(( "IopStartNetworkForRemoteBoot: Unable to open new net driver: 0x%x\n", status ));
    01443             }
    01444             if (driverHandle != NULL) {
    01445                 NtClose( driverHandle );
    01446             }
    01447
    01448             ExFreePool( fullDriverName );
    01449
    01450         } else {
    01451
    01452             //
    01453             //  this is not a fatal error, the redir should pin it eventually
    01454             //
    01455
    01456             KdPrint(( "IopStartNetworkForRemoteBoot: Unable to allocate buffer to pin netcard driver\n" ));
    01457         }
    01458     }
    01459
    01460     leaveRdrHandleOpen = TRUE;
    01461 #endif // defined(REMOTE_BOOT)
    01462
    01463 cleanup:
    01464
    01465     RtlFreeUnicodeString( &computerName );
    01466     RtlFreeUnicodeString( &domainName );
    01467 #if defined(REMOTE_BOOT)
    01468     if ( NetHDCSCPartition != NULL ) {
    01469         ExFreePool( NetHDCSCPartition );
    01470     }
    01471 #else
    01472     if ( buffer != NULL ) {
    01473         ExFreePool( buffer );
    01474     }
    01475 #endif // defined(REMOTE_BOOT)
    01476
    01477     if ( dgHandle != NULL ) {
    01478         NtClose( dgHandle );
    01479     }
    01480
    01481 #if defined(REMOTE_BOOT)
    01482     //
    01483     // If requested, exit with RdrHandle still set so that we can close CSC quickly.
    01484     //
    01485
    01486     if ( !leaveRdrHandleOpen && (RdrHandle != NULL) ) {
    01487         NtClose( RdrHandle );
    01488         RdrHandle = NULL;
    01489     }
    01490 #endif // defined(REMOTE_BOOT)
    01491
    01492     return status;
    01493 }

NTSTATUS IopStartTcpIpForRemoteBoot | ( | PLOADER_PARAMETER_BLOCK | LoaderBlock | ) |

Definition at line 1834 of file netboot.c.

References _SETUP_LOADER_BLOCK::IpAddress, NT_SUCCESS, NtClose(), NtCreateFile(), NtDeviceIoControlFile(), NTSTATUS(), NULL, RtlInitUnicodeString(), _LOADER_PARAMETER_BLOCK::SetupLoaderBlock, _SETUP_LOADER_BLOCK::SubnetMask, and USHORT.

Referenced by IopInitializeBootDrivers().

    01837 {
    01838     UNICODE_STRING IpString;
    01839     NTSTATUS status = STATUS_SUCCESS;
    01840     HANDLE handle;
    01841     OBJECT_ATTRIBUTES objectAttributes;
    01842     IO_STATUS_BLOCK ioStatusBlock;
    01843     IP_SET_ADDRESS_REQUEST IpRequest;
    01844
    01845     RtlInitUnicodeString( &IpString, DD_IP_DEVICE_NAME );
    01846
    01847     InitializeObjectAttributes(
    01848         &objectAttributes,
    01849         &IpString,
    01850         OBJ_CASE_INSENSITIVE,
    01851         NULL,
    01852         NULL
    01853         );
    01854
    01855     IpRequest.Context = (USHORT)2;
    01856     IpRequest.Address = LoaderBlock->SetupLoaderBlock->IpAddress;
    01857     IpRequest.SubnetMask = LoaderBlock->SetupLoaderBlock->SubnetMask;
    01858
    01859     status = NtCreateFile(
    01860                 &handle,
    01861                 GENERIC_READ | GENERIC_WRITE,
    01862                 &objectAttributes,
    01863                 &ioStatusBlock,
    01864                 NULL,
    01865                 0,
    01866                 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    01867                 FILE_OPEN,
    01868                 FILE_SYNCHRONOUS_IO_NONALERT,
    01869                 NULL,
    01870                 0
    01871                 );
    01872     if ( !NT_SUCCESS(status) ) {
    01873         KdPrint(( "IopStartTcpIpForRemoteBoot: Unable to open IP: %x\n", status ));
    01874         goto cleanup;
    01875     }
    01876
    01877     status = NtDeviceIoControlFile(
    01878                 handle,
    01879                 NULL,
    01880                 NULL,
    01881                 NULL,
    01882                 &ioStatusBlock,
    01883                 IOCTL_IP_SET_ADDRESS_DUP,
    01884                 &IpRequest,
    01885                 sizeof(IP_SET_ADDRESS_REQUEST),
    01886                 NULL,
    01887                 0
    01888                 );
    01889
    01890     NtClose( handle );
    01891
    01892     if ( !NT_SUCCESS(status) ) {
    01893         KdPrint(( "IopStartTcpIpForRemoteBoot: Unable to IOCTL IP: %x\n", status ));
    01894         goto cleanup;
    01895     }
    01896
    01897 cleanup:
    01898
    01899     return status;
    01900 }

NTSTATUS IopSynchronousApiServiceTail | ( | IN NTSTATUS | ReturnedStatus,
|  | IN PKEVENT | Event,
|  | IN PIRP | Irp,
|  | IN KPROCESSOR_MODE | RequestorMode,
|  | IN PIO_STATUS_BLOCK | LocalIoStatus,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock
| ) |

Definition at line 6926 of file internal.c.

References Event(), EXCEPTION_EXECUTE_HANDLER, Executive, ExFreePool(), FALSE, IopCancelAlertedRequest(), Irp, KeWaitForSingleObject(), NTSTATUS(), NULL, and PAGED_CODE.

Referenced by IopSetEaOrQuotaInformationFile(), NtFlushBuffersFile(), NtQueryEaFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtSetEaFile(), NtSetVolumeInformationFile(), and NtUnlockFile().

    06937                    :
    06938
    06939     This routine is invoked when a synchronous API is invoked for a file
    06940     that has been opened for asynchronous I/O.  This function synchronizes
    06941     the completion of the I/O operation on the file.
    06942
    06943 Arguments:
    06944
    06945     ReturnedStatus - Supplies the status that was returned from the call to
    06946         IoCallDriver.
    06947
    06948     Event - Address of the allocated kernel event to be used for synchronization
    06949         of the I/O operation.
    06950
    06951     Irp - Address of the I/O Request Packet submitted to the driver.
    06952
    06953     RequestorMode - Processor mode of the caller when the operation was
    06954         requested.
    06955
    06956     LocalIoStatus - Address of the I/O status block used to capture the final
    06957         status by the service itself.
    06958
    06959     IoStatusBlock - Address of the I/O status block supplied by the caller of
    06960         the system service.
    06961
    06962 Return Value:
    06963
    06964     The function value is the final status of the operation.
    06965
    06966
    06967 --*/
    06968
    06969 {
    06970     NTSTATUS status;
    06971
    06972     PAGED_CODE();
    06973
    06974     //
    06975     // This is a normal synchronous I/O operation, as opposed to a
    06976     // serialized synchronous I/O operation.  For this case, wait for
    06977     // the local event and copy the final status information back to
    06978     // the caller.
    06979     //
    06980
    06981     status = ReturnedStatus;
    06982
    06983     if (status == STATUS_PENDING) {
    06984
    06985         status = KeWaitForSingleObject( Event,
    06986                                         Executive,
    06987                                         RequestorMode,
    06988                                         FALSE,
    06989                                         (PLARGE_INTEGER) NULL );
    06990
    06991         if (status == STATUS_ALERTED || status == STATUS_USER_APC) {
    06992
    06993             //
    06994             // The wait request has ended either because the thread was
    06995             // alerted or an APC was queued to this thread, because of
    06996             // thread rundown or CTRL/C processing.  In either case, try
    06997             // to bail out of this I/O request carefully so that the IRP
    06998             // completes before this routine exists or the event will not
    06999             // be around to set to the Signaled state.
    07000             //
    07001
    07002             IopCancelAlertedRequest( Event, Irp );
    07003
    07004         }
    07005
    07006         status = LocalIoStatus->Status;
    07007     }
    07008
    07009     try {
    07010
    07011         *IoStatusBlock = *LocalIoStatus;
    07012
    07013     } except(EXCEPTION_EXECUTE_HANDLER) {
    07014
    07015         //
    07016         // An exception occurred attempting to write the caller's I/O
    07017         // status block.  Simply change the final status of the operation
    07018         // to the exception code.
    07019         //
    07020
    07021         status = GetExceptionCode();
    07022     }
    07023
    07024     ExFreePool( Event );
    07025
    07026     return status;
    07027 }

NTSTATUS IopSynchronousServiceTail | ( | IN PDEVICE_OBJECT | DeviceObject,
|  | IN PIRP | Irp,
|  | IN PFILE_OBJECT | FileObject,
|  | IN BOOLEAN | DeferredIoCompletion,
|  | IN KPROCESSOR_MODE | RequestorMode,
|  | IN BOOLEAN | SynchronousIo,
|  | IN TRANSFER_TYPE | TransferType
| ) |

Definition at line 7030 of file internal.c.

References APC_LEVEL, ASSERT, Executive, FO_ALERTABLE_IO, IoCallDriver, IopCancelAlertedRequest(), IopCompleteRequest(), IopQueueThreadIrp, IopReleaseFileObjectLock, IopUpdateOtherOperationCount(), IopUpdateReadOperationCount(), IopUpdateWriteOperationCount(), Irp, KeLowerIrql(), KeRaiseIrql(), KeWaitForSingleObject(), NTSTATUS(), NULL, OtherTransfer, PAGED_CODE, _IRP::PendingReturned, PKNORMAL_ROUTINE, ReadTransfer, SynchronousIo, _IRP::Tail, TRANSFER_TYPE, and WriteTransfer.

Referenced by IopSetEaOrQuotaInformationFile(), IopXxxControlFile(), NtFlushBuffersFile(), NtLockFile(), NtNotifyChangeDirectoryFile(), NtQueryDirectoryFile(), NtQueryEaFile(), NtQueryQuotaInformationFile(), NtQueryVolumeInformationFile(), NtReadFile(), NtReadFileScatter(), NtSetEaFile(), NtSetVolumeInformationFile(), NtUnlockFile(), NtWriteFile(), and NtWriteFileGather().

    07042                    :
    07043
    07044     This routine is invoked to complete the operation of a system service.
    07045     It queues the IRP to the thread's queue, updates the transfer count,
    07046     calls the driver, and finally synchronizes completion of the I/O.
    07047
    07048 Arguments:
    07049
    07050     DeviceObject - Device on which the I/O is to occur.
    07051
    07052     Irp - I/O Request Packet representing the I/O operation.
    07053
    07054     FileObject - File object for this open instantiation.
    07055
    07056     DeferredIoCompletion - Indicates whether deferred completion is possible.
    07057
    07058     RequestorMode - Mode in which request was made.
    07059
    07060     SynchronousIo - Indicates whether the operation is to be synchronous.
    07061
    07062     TransferType - Type of transfer being performed: read, write, or other.
    07063
    07064 Return Value:
    07065
    07066     The function value is the final status of the operation.
    07067
    07068 --*/
    07069
    07070 {
    07071     NTSTATUS status;
    07072
    07073     PAGED_CODE();
    07074
    07075     //
    07076     // Insert the packet at the head of the IRP list for the thread.
    07077     //
    07078
    07079     IopQueueThreadIrp( Irp );
    07080
    07081     //
    07082     // Update the operation count statistic for the current process.
    07083     //
    07084
    07085     switch( TransferType ) {
    07086
    07087     case ReadTransfer:
    07088         IopUpdateReadOperationCount();
    07089         break;
    07090
    07091     case WriteTransfer:
    07092         IopUpdateWriteOperationCount();
    07093         break;
    07094
    07095     case OtherTransfer:
    07096         IopUpdateOtherOperationCount();
    07097         break;
    07098     }
    07099
    07100     //
    07101     // Now simply invoke the driver at its dispatch entry with the IRP.
    07102     //
    07103
    07104     status = IoCallDriver( DeviceObject, Irp );
    07105
    07106     //
    07107     // If deferred I/O completion is possible, check for pending returned
    07108     // from the driver.  If the driver did not return pending, then the
    07109     // packet has not actually been completed yet, so complete it here.
    07110     //
    07111
    07112     if (DeferredIoCompletion) {
    07113
    07114         if (status != STATUS_PENDING) {
    07115
    07116             //
    07117             // The I/O operation was completed without returning a status of
    07118             // pending.  This means that at this point, the IRP has not been
    07119             // fully completed.  Complete it now.
    07120             //
    07121
    07122             PKNORMAL_ROUTINE normalRoutine;
    07123             PVOID normalContext;
    07124             KIRQL irql;
    07125
    07126             ASSERT( !Irp->PendingReturned );
    07127
    07128             KeRaiseIrql( APC_LEVEL, &irql );
    07129             IopCompleteRequest( &Irp->Tail.Apc,
    07130                                 &normalRoutine,
    07131                                 &normalContext,
    07132                                 (PVOID *) &FileObject,
    07133                                 &normalContext );
    07134             KeLowerIrql( irql );
    07135         }
    07136     }
    07137
    07138     //
    07139     // If this operation was a synchronous I/O operation, check the return
    07140     // status to determine whether or not to wait on the file object.  If
    07141     // the file object is to be waited on, wait for the operation to complete
    07142     // and obtain the final status from the file object itself.
    07143     //
    07144
    07145     if (SynchronousIo) {
    07146
    07147         if (status == STATUS_PENDING) {
    07148
    07149             status = KeWaitForSingleObject( &FileObject->Event,
    07150                                             Executive,
    07151                                             RequestorMode,
    07152                                             (BOOLEAN) ((FileObject->Flags & FO_ALERTABLE_IO) != 0),
    07153                                             (PLARGE_INTEGER) NULL );
    07154
    07155             if (status == STATUS_ALERTED || status == STATUS_USER_APC) {
    07156
    07157                 //
    07158                 // The wait request has ended either because the thread was alerted
    07159                 // or an APC was queued to this thread, because of thread rundown or
    07160                 // CTRL/C processing.  In either case, try to bail out of this I/O
    07161                 // request carefully so that the IRP completes before this routine
    07162                 // exists so that synchronization with the file object will remain
    07163                 // intact.
    07164                 //
    07165
    07166                 IopCancelAlertedRequest( &FileObject->Event, Irp );
    07167
    07168             }
    07169
    07170             status = FileObject->FinalStatus;
    07171
    07172         }
    07173
    07174         IopReleaseFileObjectLock( FileObject );
    07175
    07176     }
    07177
    07178     return status;
    07179 }

VOID IopTimerDispatch | ( | IN PKDPC | Dpc,
|  | IN PVOID | DeferredContext,
|  | IN PVOID | SystemArgument1,
|  | IN PVOID | SystemArgument2
| ) |

Definition at line 7182 of file internal.c.

References _IO_TIMER::Context, _IO_TIMER::DeviceObject, IO_TIMER, IopTimerCount, IopTimerLock, IopTimerQueueHead, PIO_TIMER, _IO_TIMER::TimerFlag, and _IO_TIMER::TimerRoutine.

Referenced by IoInitSystem().

    07191                    :
    07192
    07193     This routine scans the I/O system timer database and invokes each driver
    07194     that has enabled a timer in the list, once every second.
    07195
    07196 Arguments:
    07197
    07198     Dpc - Supplies a pointer to a control object of type DPC.
    07199
    07200     DeferredContext - Optional deferred context;  not used.
    07201
    07202     SystemArgument1 - Optional argument 1;  not used.
    07203
    07204     SystemArgument2 - Optional argument 2;  not used.
    07205
    07206 Return Value:
    07207
    07208     None.
    07209
    07210 --*/
    07211
    07212 {
    07213     PLIST_ENTRY timerEntry;
    07214     PIO_TIMER timer;
    07215     LARGE_INTEGER deltaTime;
    07216     KIRQL irql;
    07217     ULONG i;
    07218
    07219     UNREFERENCED_PARAMETER( Dpc );
    07220     UNREFERENCED_PARAMETER( DeferredContext );
    07221     UNREFERENCED_PARAMETER( SystemArgument1 );
    07222     UNREFERENCED_PARAMETER( SystemArgument2 );
    07223
    07224     //
    07225     // Check to see whether or not there are any timers in the queue that
    07226     // have been enabled.  If so, then walk the list and invoke all of the
    07227     // drivers' routines.  Note that if the counter changes, which it can
    07228     // because the spin lock is not owned, then a timer routine may be
    07229     // missed.  However, this is acceptable, since the driver inserting the
    07230     // entry could be context switched away from, etc.  Therefore, this is
    07231     // not a critical resource for the most part.
    07232     //
    07233
    07234     if (IopTimerCount) {
    07235
    07236         //
    07237         // There is at least one timer entry in the queue that is enabled.
    07238         // Walk the queue and invoke each specified timer routine.
    07239         //
    07240
    07241         ExAcquireSpinLock( &IopTimerLock, &irql );
    07242         i = IopTimerCount;
    07243         timerEntry = IopTimerQueueHead.Flink;
    07244
    07245         //
    07246         // For each entry found that is enabled, invoke the driver's routine
    07247         // with its specified context parameter.  The local count is used
    07248         // to abort the queue traversal when there are more entries in the
    07249         // queue, but they are not enabled.
    07250         //
    07251
    07252         for (timerEntry = IopTimerQueueHead.Flink;
    07253              (timerEntry != &IopTimerQueueHead) && i;
    07254              timerEntry = timerEntry->Flink ) {
    07255
    07256             timer = CONTAINING_RECORD( timerEntry, IO_TIMER, TimerList );
    07257
    07258             if (timer->TimerFlag) {
    07259                 timer->TimerRoutine( timer->DeviceObject, timer->Context );
    07260                 i--;
    07261             }
    07262         }
    07263         ExReleaseSpinLock( &IopTimerLock, irql );
    07264     }
    07265 }

NTSTATUS IopTrackLink | ( | IN PFILE_OBJECT | FileObject,
|  | IN OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN PFILE_TRACKING_INFORMATION | FileInformation,
|  | IN ULONG | Length,
|  | IN PKEVENT | Event,
|  | IN KPROCESSOR_MODE | RequestorMode
| ) |

Definition at line 7272 of file internal.c.

References Event(), ExAllocatePoolWithQuota, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, FILE_VOLUMEID_WITH_TYPE, IoFileObjectType, IopGetSetObjectId(), IopGetVolumeId(), IopIsSameMachine(), IopMarshalIds(), IopSendMessageToTrackService(), IopSetRemoteLink(), IsFileLocal, KernelMode, KeSetEvent(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), PAGED_CODE, PagedPool, RtlCompareMemoryUlong(), _TRACKING_BUFFER::TrackingInformation, and TRUE.

Referenced by NtSetInformationFile().

    07283                    :
    07284
    07285     This routine is invoked to track a link.  It tracks the source file's Object
    07286     ID to the target file so that links to the source will follow to the new
    07287     location of the target.
    07288
    07289 Arguments:
    07290
    07291     FileObject - Supplies a pointer to the referenced source file object.
    07292
    07293     IoStatusBlock - Pointer to the caller's I/O status block.
    07294
    07295     FileInformation - A buffer containing the parameters for the move that was
    07296         performed.
    07297
    07298     Length - Specifies the length of the FileInformation buffer.
    07299
    07300     Event - An event to be set to the Signaled state once the operation has been
    07301         performed, provided it was successful.
    07302
    07303     RequestorMode - Requestor mode of the caller.
    07304
    07305 N.B. - Note that the presence of an event indicates that the source file was
    07306     opened for asynchronous I/O, otherwise it was opened for synchronous I/O.
    07307
    07308 Return Value:
    07309
    07310     The status returned is the final completion status of the operation.
    07311
    07312
    07313 --*/
    07314
    07315 {
    07316     PFILE_TRACKING_INFORMATION trackingInfo = NULL;
    07317     PFILE_OBJECT dstFileObject = NULL;
    07318     FILE_VOLUMEID_WITH_TYPE SourceVolumeId;
    07319     FILE_OBJECTID_BUFFER SourceObjectId;
    07320     FILE_OBJECTID_BUFFER NormalizedObjectId;
    07321     FILE_OBJECTID_BUFFER CrossVolumeObjectId;
    07322     FILE_VOLUMEID_WITH_TYPE TargetVolumeId;
    07323     FILE_OBJECTID_BUFFER TargetObjectId;
    07324     TRACKING_BUFFER trackingBuffer;
    07325     NTSTATUS status;
    07326
    07327     PAGED_CODE();
    07328
    07329     //
    07330     // Begin by capturing the caller's buffer, if required.
    07331     //
    07332
    07333     if (RequestorMode != KernelMode) {
    07334
    07335         try {
    07336             trackingInfo = ExAllocatePoolWithQuota( PagedPool,
    07337                                                     Length );
    07338             RtlCopyMemory( trackingInfo, FileInformation, Length );
    07339
    07340             if (!trackingInfo->DestinationFile ||
    07341                ((Length - FIELD_OFFSET( FILE_TRACKING_INFORMATION, ObjectInformation ))
    07342                 < trackingInfo->ObjectInformationLength)) {
    07343                 ExFreePool( trackingInfo );
    07344                 return STATUS_INVALID_PARAMETER;
    07345             }
    07346
    07347         } except(EXCEPTION_EXECUTE_HANDLER) {
    07348
    07349             //
    07350             // An exception was incurred while allocating the intermediary
    07351             // system buffer or while copying the caller's data into the
    07352             // buffer.  Cleanup and return an appropriate error status code.
    07353             //
    07354
    07355             if (trackingInfo) {
    07356                 ExFreePool( trackingInfo );
    07357             }
    07358
    07359             return GetExceptionCode();
    07360         }
    07361     } else {
    07362         trackingInfo = FileInformation;
    07363     }
    07364
    07365     //
    07366     // If a destination file handle was specified, convert it to a pointer to
    07367     // a file object.
    07368     //
    07369
    07370     if (trackingInfo->DestinationFile) {
    07371         status = ObReferenceObjectByHandle( trackingInfo->DestinationFile,
    07372                                             FILE_WRITE_DATA,
    07373                                             IoFileObjectType,
    07374                                             RequestorMode,
    07375                                             (PVOID *) &dstFileObject,
    07376                                             NULL );
    07377         if (!NT_SUCCESS( status )) {
    07378             if (RequestorMode != KernelMode) {
    07379                 ExFreePool( trackingInfo );
    07380             }
    07381             return status;
    07382         }
    07383     }
    07384
    07385     try {
    07386
    07387         //
    07388         // Determine whether this is a local or a remote link tracking
    07389         // operation.
    07390         //
    07391
    07392         if (IsFileLocal( FileObject )) {
    07393
    07394             //
    07395             // The source file, i.e., the one being moved, is a file local to
    07396             // this system.  Determine the form of the target file and track
    07397             // it accordingly.
    07398             //
    07399
    07400             if (trackingInfo->DestinationFile) {
    07401
    07402                 if (IsFileLocal( dstFileObject )) {
    07403
    07404                     BOOLEAN IdSetOnTarget = FALSE;
    07405
    07406                     //
    07407                     // The target file is specified as a handle and it is local.
    07408                     // Simply perform the query and set locally.  Note that if
    07409                     // the source file does not have an object ID, then no
    07410                     // tracking will be performed, but it will appear as if the
    07411                     // operation worked.
    07412                     //
    07413
    07414                     status = IopGetSetObjectId( FileObject,
    07415                                                 &SourceObjectId,
    07416                                                 sizeof( SourceObjectId ),
    07417                                                 FSCTL_GET_OBJECT_ID );
    07418
    07419                     if (status == STATUS_OBJECT_NAME_NOT_FOUND) {
    07420                         return(STATUS_SUCCESS);
    07421                     }
    07422
    07423                     if (!NT_SUCCESS( status )) {
    07424                         return status;
    07425                     }
    07426
    07427                     //
    07428                     // If the extended info field is zero then this file
    07429                     // has no interesting tracking information.
    07430                     //
    07431                     if (RtlCompareMemoryUlong(SourceObjectId.BirthObjectId,
    07432                                        sizeof(SourceObjectId.BirthObjectId),
    07433                                        0) == sizeof(SourceObjectId.BirthObjectId)) {
    07434                             return (STATUS_SUCCESS);
    07435                     }
    07436
    07437
    07438                     //
    07439                     // Get the volume ID of the source and destination
    07440                     //
    07441
    07442                     status = IopGetVolumeId( dstFileObject,
    07443                                              &TargetVolumeId,
    07444                                              sizeof( TargetVolumeId ) );
    07445                     if (!NT_SUCCESS( status )) {
    07446                         return status;
    07447                     }
    07448
    07449                     status = IopGetVolumeId( FileObject,
    07450                                              &SourceVolumeId,
    07451                                              sizeof( SourceVolumeId ) );
    07452                     if (!NT_SUCCESS( status )) {
    07453                         return status;
    07454                     }
    07455
    07456                     //
    07457                     // Delete the ID from the source now, since the
    07458                     // target may be on the same volume.  If there's a
    07459                     // subsequent error, we'll try to restore it.
    07460                     //
    07461
    07462                     status = IopGetSetObjectId( FileObject,
    07463                                                 NULL,
    07464                                                 0,
    07465                                                 FSCTL_DELETE_OBJECT_ID );
    07466                     if (!NT_SUCCESS( status )) {
    07467                         return status;
    07468                     }
    07469
    07470
    07471                     //
    07472                     // Set the ID on the target.  If it's a cross-volume
    07473                     // move, set the bit that indicates same.
    07474                     //
    07475
    07476                     CrossVolumeObjectId = TargetObjectId = SourceObjectId;
    07477                     if( !RtlEqualMemory( &TargetVolumeId.VolumeId[0],
    07478                                          &SourceVolumeId.VolumeId[0],
    07479                                          sizeof(SourceVolumeId.VolumeId) )) {
    07480                         CrossVolumeObjectId.BirthVolumeId[0] |= 1;
    07481                     }
    07482
    07483                     status = IopGetSetObjectId( dstFileObject,
    07484                                                 &CrossVolumeObjectId,
    07485                                                 sizeof( CrossVolumeObjectId ),
    07486                                                 FSCTL_SET_OBJECT_ID );
    07487
    07488                     if( status == STATUS_DUPLICATE_NAME ||
    07489                         status == STATUS_OBJECT_NAME_COLLISION ) {
    07490
    07491                         // This object ID is already in use on the target volume,
    07492                         // or the dest file already has an object ID.
    07493                         // Get the file's ID (or have NTFS generate a new one).
    07494
    07495                         status = IopGetSetObjectId( dstFileObject,
    07496                                                     &TargetObjectId,
    07497                                                     sizeof(TargetObjectId),
    07498                                                     FSCTL_CREATE_OR_GET_OBJECT_ID );
    07499                         if( NT_SUCCESS(status) ) {
    07500
    07501                             // Write the birth ID
    07502
    07503                             status = IopGetSetObjectId( dstFileObject,
    07504                                                         &CrossVolumeObjectId.ExtendedInfo[0],
    07505                                                         sizeof( CrossVolumeObjectId.ExtendedInfo ),
    07506                                                         FSCTL_SET_OBJECT_ID_EXTENDED );
    07507                         }
    07508                     }
    07509
    07510                     if( NT_SUCCESS(status) ) {
    07511
    07512                         IdSetOnTarget = TRUE;
    07513
    07514                         // If this was a cross-volume move, notify the tracking service.
    07515
    07516                         if( !RtlEqualMemory( &TargetVolumeId.VolumeId[0],
    07517                                              &SourceVolumeId.VolumeId[0],
    07518                                              sizeof(SourceVolumeId.VolumeId) )) {
    07519
    07520                             IopMarshalIds( &trackingBuffer, &TargetVolumeId, &TargetObjectId, trackingInfo );
    07521
    07522                             // Bit 0 must be reset before notifying tracking service
    07523                             NormalizedObjectId = SourceObjectId;
    07524                             NormalizedObjectId.BirthVolumeId[0] &= 0xfe;
    07525
    07526                             status = IopSendMessageToTrackService( &SourceVolumeId,
    07527                                                                    &NormalizedObjectId,
    07528                                                                    &trackingBuffer.TrackingInformation );
    07529                         }
    07530                     }
    07531
    07532                     //
    07533                     // If there was an error after the ObjectID was deleted
    07534                     // from the source.  Try to restore it before returning.
    07535                     //
    07536
    07537                     if( !NT_SUCCESS(status) ) {
    07538                         NTSTATUS statusT = STATUS_SUCCESS;
    07539
    07540                         if( IdSetOnTarget ) {
    07541
    07542                             if( RtlEqualMemory( &TargetObjectId.ObjectId,
    07543                                                 &SourceObjectId.ObjectId,
    07544                                                 sizeof(TargetObjectId.ObjectId) )) {
    07545
    07546                                 // This ID was set with FSCTL_SET_OBJECT_ID
    07547                                 statusT = IopGetSetObjectId( dstFileObject,
    07548                                                              NULL,
    07549                                                              0,
    07550                                                              FSCTL_DELETE_OBJECT_ID );
    07551
    07552                             } else {
    07553
    07554                                 // Restore the target's extended data.
    07555
    07556                                 statusT = IopGetSetObjectId( dstFileObject,
    07557                                                              &TargetObjectId.ExtendedInfo[0],
    07558                                                              sizeof(TargetObjectId.ExtendedInfo),
    07559                                                              FSCTL_SET_OBJECT_ID_EXTENDED );
    07560                             }
    07561                         }
    07562
    07563                         if( NT_SUCCESS( statusT )) {
    07564
    07565                             IopGetSetObjectId( FileObject,
    07566                                                &SourceObjectId,
    07567                                                sizeof(SourceObjectId),
    07568                                                FSCTL_SET_OBJECT_ID );
    07569                         }
    07570
    07571                         return status;
    07572                     }
    07573
    07574
    07575                 } else {    // if (IsFileLocal( dstFileObject ))
    07576
    07577                     //
    07578                     // The source file is local, but the destination file object
    07579                     // is remote.  For this case query the target file's object
    07580                     // ID and notify the link tracking system that the file has
    07581                     // been moved across systems.
    07582                     //
    07583
    07584                     //
    07585                     // Begin by ensuring that the source file has an object ID
    07586                     // already.  If not, then just make it appear as if the
    07587                     // operation worked.
    07588                     //
    07589
    07590                     status = IopGetSetObjectId( FileObject,
    07591                                                 &SourceObjectId,
    07592                                                 sizeof( SourceObjectId ),
    07593                                                 FSCTL_GET_OBJECT_ID );
    07594                     if (!NT_SUCCESS( status )) {
    07595                         return STATUS_SUCCESS;
    07596                     }
    07597
    07598
    07599                     //
    07600                     // If the extended info field is zero then this file
    07601                     // has no interesting tracking information.
    07602                     //
    07603                     if (RtlCompareMemoryUlong(&SourceObjectId.BirthObjectId,
    07604                                        sizeof(SourceObjectId.BirthObjectId),
    07605                                        0) == sizeof(SourceObjectId.BirthObjectId)) {
    07606                             return (STATUS_SUCCESS);
    07607                     }
    07608
    07609                     //
    07610                     // Query the volume ID of the target.
    07611                     //
    07612
    07613                     status = IopGetSetObjectId( dstFileObject,
    07614                                                 &TargetVolumeId,
    07615                                                 sizeof( FILE_VOLUMEID_WITH_TYPE ),
    07616                                                 FSCTL_LMR_GET_LINK_TRACKING_INFORMATION );
    07617                     if (!NT_SUCCESS( status )) {
    07618                         return status;
    07619                     }
    07620
    07621                     //
    07622                     // Query the object ID of the target.
    07623                     //
    07624
    07625                     status = IopGetSetObjectId( dstFileObject,
    07626                                                 &TargetObjectId,
    07627                                                 sizeof( TargetObjectId ),
    07628                                                 FSCTL_CREATE_OR_GET_OBJECT_ID );
    07629                     if (!NT_SUCCESS( status )) {
    07630                         return status;
    07631                     }
    07632
    07633                     //
    07634                     // Notify the tracking system of the move.
    07635                     //
    07636
    07637                     IopMarshalIds( &trackingBuffer, &TargetVolumeId, &TargetObjectId, trackingInfo );
    07638                     status = IopTrackLink( FileObject,
    07639                                            IoStatusBlock,
    07640                                            &trackingBuffer.TrackingInformation,
    07641                                            FIELD_OFFSET( FILE_TRACKING_INFORMATION,
    07642                                                 ObjectInformation ) +
    07643                                                     trackingBuffer.TrackingInformation.ObjectInformationLength,
    07644                                            Event,
    07645                                            KernelMode );
    07646                     if (!NT_SUCCESS( status )) {
    07647                         return status;
    07648                     }
    07649
    07650                     //
    07651                     // Delete the ID from the source
    07652                     //
    07653
    07654                     status = IopGetSetObjectId( FileObject,
    07655                                                 NULL,
    07656                                                 0,
    07657                                                 FSCTL_DELETE_OBJECT_ID );
    07658                     if( !NT_SUCCESS( status )) {
    07659                         return status;
    07660                     }
    07661
    07662                     //
    07663                     // Set the Birth ID on the target, turning on the bit
    07664                     // that indicates that this file has been involved in a cross-
    07665                     // volume move.
    07666                     //
    07667
    07668                     CrossVolumeObjectId = SourceObjectId;
    07669                     CrossVolumeObjectId.BirthVolumeId[0] |= 1;
    07670
    07671                     status = IopGetSetObjectId( dstFileObject,
    07672                                                 &CrossVolumeObjectId.ExtendedInfo[0],
    07673                                                 sizeof( CrossVolumeObjectId.ExtendedInfo ),
    07674                                                 FSCTL_SET_OBJECT_ID_EXTENDED );
    07675                     if (!NT_SUCCESS( status )) {
    07676
    07677                         // Try to restore the source
    07678                         IopGetSetObjectId( FileObject,
    07679                                            &SourceObjectId,
    07680                                            sizeof(SourceObjectId),
    07681                                            FSCTL_SET_OBJECT_ID );
    07682                         return status;
    07683                     }
    07684
    07685
    07686                 }   // if (IsFileLocal( dstFileObject ))
    07687
    07688             } else {    // if (trackingInfo->DestinationFile)
    07689
    07690                 //
    07691                 // A destination file handle was not specified.  Simply query
    07692                 // the source file's object ID and call the link tracking code.
    07693                 // Note that the function input buffer contains the volume ID
    07694                 // and file object ID of the target.  Note also that it is
    07695                 // assumed that the source file has an object ID.
    07696                 //
    07697
    07698                 status = IopGetVolumeId( FileObject,
    07699                                          &SourceVolumeId,
    07700                                          sizeof( SourceVolumeId ) );
    07701                 if (!NT_SUCCESS( status )) {
    07702                     return status;
    07703                 }
    07704
    07705                 status = IopGetSetObjectId( FileObject,
    07706                                             &SourceObjectId,
    07707                                             sizeof( SourceObjectId ),
    07708                                             FSCTL_GET_OBJECT_ID );
    07709                 if (!NT_SUCCESS( status )) {
    07710                     return status;
    07711                 }
    07712
    07713                 //
    07714                 // If the extended info field is zero then this file
    07715                 // has no interesting tracking information.
    07716                 //
    07717                 if (RtlCompareMemoryUlong(SourceObjectId.BirthObjectId,
    07718                                        sizeof(SourceObjectId.BirthObjectId),
    07719                                        0) == sizeof(SourceObjectId.BirthObjectId)) {
    07720                             return (STATUS_SUCCESS);
    07721                 }
    07722                 //
    07723                 // Inform the user-mode link tracking service that the file
    07724                 // has been moved.
    07725                 //
    07726
    07727                 NormalizedObjectId = SourceObjectId;
    07728                 NormalizedObjectId.BirthVolumeId[0] &= 0xfe;
    07729
    07730                 status = IopSendMessageToTrackService( &SourceVolumeId,
    07731                                                        &NormalizedObjectId,
    07732                                                        FileInformation );
    07733                 if (!NT_SUCCESS( status )) {
    07734                     return status;
    07735                 }
    07736
    07737             }   // if (trackingInfo->DestinationFile) ... else
    07738
    07739         } else {    // if (IsFileLocal( FileObject ))
    07740
    07741             //
    07742             // The source file is remote.  For this case, remote the operation
    07743             // to the system on which the source file is located.  Begin by
    07744             // ensuring that the source file actually has an object ID.  If
    07745             // not, then get out now since there is nothing to be done.
    07746             //
    07747
    07748             status = IopGetSetObjectId( FileObject,
    07749                                         &SourceObjectId,
    07750                                         sizeof( SourceObjectId ),
    07751                                         FSCTL_GET_OBJECT_ID );
    07752
    07753             if (status == STATUS_OBJECT_NAME_NOT_FOUND)
    07754             {
    07755                 return STATUS_SUCCESS;
    07756             }
    07757
    07758             if (!NT_SUCCESS( status )) {
    07759                 return status;
    07760             }
    07761
    07762             //
    07763             // If the extended info field is zero then this file
    07764             // has no interesting tracking information.
    07765             //
    07766             if (RtlCompareMemoryUlong(SourceObjectId.BirthObjectId,
    07767                                       sizeof(SourceObjectId.BirthObjectId),
    07768                                       0) == sizeof(SourceObjectId.BirthObjectId)) {
    07769                 return (STATUS_SUCCESS);
    07770             }
    07771             if (trackingInfo->DestinationFile) {
    07772
    07773                 //
    07774                 // A handle was specified for the destination file.  Determine
    07775                 // whether it is local or remote.  If remote and both handles
    07776                 // refer to the same machine, then ship the entire API to that
    07777                 // machine and have it perform the operation.
    07778                 //
    07779                 // Otherwise, query the target file's object ID, and then redo
    07780                 // the operation.  This will cause the API to be remoted to the
    07781                 // machine where the source file resides.
    07782                 //
    07783
    07784                 if (IsFileLocal( dstFileObject )) {
    07785
    07786                     //
    07787                     // The source is remote and the destination is local, so
    07788                     // query the object ID of the target and recursively track
    07789                     // the link from the source file's remote node.
    07790                     //
    07791
    07792                     status = IopGetVolumeId( dstFileObject,
    07793                                              &TargetVolumeId,
    07794                                              sizeof( TargetVolumeId ) );
    07795                     if (!NT_SUCCESS( status )) {
    07796                         return status;
    07797                     }
    07798
    07799                     status = IopGetSetObjectId( dstFileObject,
    07800                                                 &TargetObjectId,
    07801                                                 sizeof( TargetObjectId ),
    07802                                                 FSCTL_CREATE_OR_GET_OBJECT_ID );
    07803                     if (!NT_SUCCESS( status )) {
    07804                         return status;
    07805                     }
    07806
    07807
    07808                     //
    07809                     // Notify the tracking system of the move.
    07810                     //
    07811
    07812                     IopMarshalIds( &trackingBuffer, &TargetVolumeId, &TargetObjectId, trackingInfo );
    07813
    07814                     status = IopTrackLink( FileObject,
    07815                                            IoStatusBlock,
    07816                                            &trackingBuffer.TrackingInformation,
    07817                                            FIELD_OFFSET( FILE_TRACKING_INFORMATION,
    07818                                                 ObjectInformation ) +
    07819                                                     trackingBuffer.TrackingInformation.ObjectInformationLength,
    07820                                            Event,
    07821                                            KernelMode );
    07822                     if( !NT_SUCCESS(status) ) {
    07823                         return status;
    07824                     }
    07825
    07826                     //
    07827                     //  Delete the ID from the source
    07828                     //
    07829
    07830                     status = IopGetSetObjectId( FileObject,
    07831                                                 NULL,
    07832                                                 0,
    07833                                                 FSCTL_DELETE_OBJECT_ID );
    07834                     if( !NT_SUCCESS( status )) {
    07835                         return status;
    07836                     }
    07837
    07838                     //
    07839                     // Set the birth ID on the target, also turning on the bit
    07840                     // that indicates that this file has moved across volumes.
    07841                     //
    07842
    07843                     CrossVolumeObjectId = SourceObjectId;
    07844                     CrossVolumeObjectId.BirthVolumeId[0] |= 1;
    07845
    07846                     status = IopGetSetObjectId( dstFileObject,
    07847                                                 &CrossVolumeObjectId.ExtendedInfo[0],
    07848                                                 sizeof( CrossVolumeObjectId.ExtendedInfo ),
    07849                                                 FSCTL_SET_OBJECT_ID_EXTENDED );
    07850
    07851                     if( !NT_SUCCESS( status )) {
    07852
    07853                         IopGetSetObjectId( FileObject,
    07854                                            &SourceObjectId,
    07855                                            sizeof(SourceObjectId),
    07856                                            FSCTL_SET_OBJECT_ID );
    07857                         return status;
    07858                     }
    07859
    07860                 }   // if (IsFileLocal( dstFileObject ))
    07861
    07862                 else if (!IopIsSameMachine( FileObject, trackingInfo->DestinationFile)) {
    07863
    07864                     //
    07865                     // The source and the target are remote from each other and from
    07866                     // this machine.  Query the object ID of the target and recursively
    07867                     // track the link from the source file's remote node.
    07868                     //
    07869
    07870                     //
    07871                     // Query the volume ID of the target.
    07872                     //
    07873
    07874                     status = IopGetSetObjectId( dstFileObject,
    07875                                                 &TargetVolumeId,
    07876                                                 sizeof( FILE_VOLUMEID_WITH_TYPE ),
    07877                                                 FSCTL_LMR_GET_LINK_TRACKING_INFORMATION );
    07878
    07879                     if (!NT_SUCCESS( status )) {
    07880                         return status;
    07881                     }
    07882
    07883                     //
    07884                     // Query the object ID of the target.
    07885                     //
    07886
    07887                     status = IopGetSetObjectId( dstFileObject,
    07888                                                 &TargetObjectId,
    07889                                                 sizeof( TargetObjectId ),
    07890                                                 FSCTL_CREATE_OR_GET_OBJECT_ID );
    07891                     if( !NT_SUCCESS( status )) {
    07892                         return status;
    07893                     }
    07894
    07895                     //
    07896                     // Notify the tracking system of the move.
    07897                     //
    07898
    07899                     IopMarshalIds( &trackingBuffer, &TargetVolumeId, &TargetObjectId, trackingInfo );
    07900
    07901                     status = IopTrackLink( FileObject,
    07902                                            IoStatusBlock,
    07903                                            &trackingBuffer.TrackingInformation,
    07904                                            FIELD_OFFSET( FILE_TRACKING_INFORMATION,
    07905                                                 ObjectInformation ) +
    07906                                                     trackingBuffer.TrackingInformation.ObjectInformationLength,
    07907                                            Event,
    07908                                            KernelMode );
    07909                     if( !NT_SUCCESS( status )) {
    07910                         return status;
    07911                     }
    07912
    07913                     //
    07914                     // Set the birth ID on the target, turning on the bit that indicates
    07915                     // that this file has moved across volumes.
    07916                     //
    07917
    07918                     CrossVolumeObjectId = SourceObjectId;
    07919                     CrossVolumeObjectId.BirthVolumeId[0] |= 1;
    07920
    07921                     status = IopGetSetObjectId( dstFileObject,
    07922                                                 &CrossVolumeObjectId.ExtendedInfo[0],
    07923                                                 sizeof( CrossVolumeObjectId.ExtendedInfo ),
    07924                                                 FSCTL_SET_OBJECT_ID_EXTENDED );
    07925
    07926                     if( !NT_SUCCESS( status )) {
    07927                         IopGetSetObjectId( FileObject,
    07928                                            &SourceObjectId,
    07929                                            sizeof(SourceObjectId),
    07930                                            FSCTL_SET_OBJECT_ID );
    07931                         return status;
    07932                     }
    07933
    07934                 } else {    // else if (!IopIsSameMachine( FileObject, trackingInfo->DestinationFile))
    07935
    07936                     //
    07937                     // Both the source and the target are remote and they're
    07938                     // both on the same remote machine.  For this case, remote
    07939                     // the entire API using the file object pointers.
    07940                     //
    07941
    07942                     status = IopSetRemoteLink( FileObject, dstFileObject, trackingInfo );
    07943
    07944                 }   // else if (!IopIsSameMachine( FileObject, trackingInfo->DestinationFile)) ... else
    07945
    07946             } else {    // if (trackingInfo->DestinationFile)
    07947
    07948                 //
    07949                 // The source file is remote and the object ID of the target is
    07950                 // contained w/in the tracking buffer.  Simply remote the API
    07951                 // to the remote machine using the source file object pointer
    07952                 // and the object ID of the target in the buffer.
    07953                 //
    07954
    07955                 status = IopSetRemoteLink( FileObject, NULL, FileInformation );
    07956
    07957             }   // if (trackingInfo->DestinationFile) ... else
    07958         }   // if (IsFileLocal( FileObject )) ... else
    07959
    07960     } finally {
    07961
    07962         //
    07963         // Ensure that everything has been cleaned up.
    07964         //
    07965
    07966         if (RequestorMode != KernelMode && trackingInfo) {
    07967             ExFreePool( trackingInfo );
    07968         }
    07969
    07970         if (dstFileObject ) {
    07971             ObDereferenceObject( dstFileObject );
    07972         }
    07973
    07974         KeSetEvent( Event, 0, FALSE );
    07975     }
    07976
    07977     return status;
    07978 }

VOID IopUpdateOtherOperationCount | ( | VOID |  | ) |

Definition at line 12345 of file iosubs.c.

References ExInterlockedAddLargeStatistic(), IoCountOperations, IoOtherOperationCount, PsGetCurrentThread, THREAD_TO_PROCESS, and TRUE.

Referenced by IoCreateFile(), IopCloseFile(), IopGetSetSecurityObject(), IopSynchronousServiceTail(), NtCancelIoFile(), NtDeleteFile(), NtQueryAttributesFile(), NtQueryFullAttributesFile(), NtQueryInformationFile(), and NtSetInformationFile().

    12350                    :
    12351
    12352     This routine is invoked to update the operation count for the current
    12353     process to indicate that an I/O service other than a read or write
    12354     has been invoked.
    12355
    12356     There is an implicit assumption that this call is always made in the context
    12357     of the issuing thread.
    12358
    12359 Arguments:
    12360
    12361     None.
    12362
    12363 Return Value:
    12364
    12365     None.
    12366
    12367 --*/
    12368 {
    12369     if (IoCountOperations == TRUE) {
    12370         IoOtherOperationCount += 1;
    12371         ExInterlockedAddLargeStatistic( &THREAD_TO_PROCESS(PsGetCurrentThread())->OtherOperationCount, 1);
    12372     }
    12373 }

VOID IopUpdateOtherTransferCount | ( | IN ULONG | TransferCount | ) |

Definition at line 12441 of file iosubs.c.

References ExInterlockedAddLargeStatistic(), IoCountOperations, IoOtherTransferCount, PsGetCurrentThread, THREAD_TO_PROCESS, and TRUE.

Referenced by IopCompleteRequest(), and NtSetInformationFile().

    12446                    :
    12447
    12448     This routine is invoked to update the transfer count for the current
    12449     process for an operation other than a read or write system service.
    12450
    12451     There is an implicit assumption that this call is always made in the context
    12452     of the issuing thread. Also note that overflow is folded into the thread's
    12453     process.
    12454
    12455 Arguments:
    12456
    12457     TransferCount - The count of the number of bytes transferred.
    12458
    12459 Return Value:
    12460
    12461     None.
    12462
    12463 --*/
    12464 {
    12465     if (IoCountOperations == TRUE) {
    12466         ExInterlockedAddLargeStatistic( &IoOtherTransferCount, TransferCount );
    12467         ExInterlockedAddLargeStatistic( &THREAD_TO_PROCESS(PsGetCurrentThread())->OtherTransferCount, TransferCount);
    12468     }
    12469 }

VOID IopUpdateReadOperationCount | ( | VOID |  | ) |

Definition at line 12377 of file iosubs.c.

References ExInterlockedAddLargeStatistic(), IoCountOperations, IoReadOperationCount, PsGetCurrentThread, THREAD_TO_PROCESS, and TRUE.

Referenced by IopSynchronousServiceTail(), and NtReadFile().

    12383                    :
    12384
    12385     This routine is invoked to update the read operation count for the
    12386     current process to indicate that the NtReadFile system service has
    12387     been invoked.
    12388
    12389     There is an implicit assumption that this call is always made in the context
    12390     of the issuing thread.
    12391
    12392 Arguments:
    12393
    12394     None.
    12395
    12396 Return Value:
    12397
    12398     None.
    12399
    12400 --*/
    12401 {
    12402     if (IoCountOperations == TRUE) {
    12403         IoReadOperationCount += 1;
    12404         ExInterlockedAddLargeStatistic( &THREAD_TO_PROCESS(PsGetCurrentThread())->ReadOperationCount, 1);
    12405     }
    12406 }

VOID IopUpdateReadTransferCount | ( | IN ULONG | TransferCount | ) |

Definition at line 12473 of file iosubs.c.

References ExInterlockedAddLargeStatistic(), IoCountOperations, IoReadTransferCount, PsGetCurrentThread, THREAD_TO_PROCESS, and TRUE.

Referenced by IopCompleteRequest(), and NtReadFile().

    12478                    :
    12479
    12480     This routine is invoked to update the read transfer count for the
    12481     current process.
    12482
    12483     There is an implicit assumption that this call is always made in the context
    12484     of the issuing thread. Also note that overflow is folded into the thread's
    12485     process.
    12486
    12487 Arguments:
    12488
    12489     TransferCount - The count of the number of bytes transferred.
    12490
    12491 Return Value:
    12492
    12493     None.
    12494
    12495 --*/
    12496 {
    12497     if (IoCountOperations == TRUE) {
    12498         ExInterlockedAddLargeStatistic( &IoReadTransferCount, TransferCount );
    12499         ExInterlockedAddLargeStatistic( &THREAD_TO_PROCESS(PsGetCurrentThread())->ReadTransferCount, TransferCount);
    12500     }
    12501 }

VOID IopUpdateWriteOperationCount | ( | VOID |  | ) |

Definition at line 12410 of file iosubs.c.

References ExInterlockedAddLargeStatistic(), IoCountOperations, IoWriteOperationCount, PsGetCurrentThread, THREAD_TO_PROCESS, and TRUE.

Referenced by IopSynchronousServiceTail(), and NtWriteFile().

    12415                    :
    12416
    12417     This routine is invoked to update the write operation count for the
    12418     current process to indicate that the NtWriteFile service other has
    12419     been invoked.
    12420
    12421     There is an implicit assumption that this call is always made in the context
    12422     of the issuing thread.
    12423
    12424 Arguments:
    12425
    12426     None.
    12427
    12428 Return Value:
    12429
    12430     None.
    12431
    12432 --*/
    12433 {
    12434     if (IoCountOperations == TRUE) {
    12435         IoWriteOperationCount += 1;
    12436         ExInterlockedAddLargeStatistic( &THREAD_TO_PROCESS(PsGetCurrentThread())->WriteOperationCount, 1);
    12437     }
    12438 }

VOID IopUpdateWriteTransferCount | ( | IN ULONG | TransferCount | ) |

Definition at line 12504 of file iosubs.c.

References ExInterlockedAddLargeStatistic(), IoCountOperations, IoWriteTransferCount, PsGetCurrentThread, THREAD_TO_PROCESS, and TRUE.

Referenced by IopCompleteRequest(), and NtWriteFile().

    12509                    :
    12510
    12511     This routine is invoked to update the write transfer count for the
    12512     current process.
    12513
    12514     There is an implicit assumption that this call is always made in the context
    12515     of the issuing thread. Also note that overflow is folded into the thread's
    12516     process.
    12517
    12518 Arguments:
    12519
    12520     TransferCount - The count of the number of bytes transferred.
    12521
    12522 Return Value:
    12523
    12524     None.
    12525
    12526 --*/
    12527 {
    12528     if (IoCountOperations == TRUE) {
    12529         ExInterlockedAddLargeStatistic( &IoWriteTransferCount, TransferCount );
    12530         ExInterlockedAddLargeStatistic( &THREAD_TO_PROCESS(PsGetCurrentThread())->WriteTransferCount, TransferCount);
    12531     }
    12532 }

VOID IopUserCompletion | ( | IN PKAPC | Apc,
|  | IN PKNORMAL_ROUTINE * | NormalRoutine,
|  | IN PVOID * | NormalContext,
|  | IN PVOID * | SystemArgument1,
|  | IN PVOID * | SystemArgument2
| ) |

Definition at line 7981 of file internal.c.

References IoFreeIrp(), and PAGED_CODE.

Referenced by IopCompleteRequest().

    07991                    :
    07992
    07993     This routine is invoked in the final processing of an IRP.  Everything has
    07994     been completed except that the caller's APC routine must be invoked.  The
    07995     system will do this as soon as this routine exits.  The only processing
    07996     remaining to be completed by the I/O system is to free the I/O Request
    07997     Packet itself.
    07998
    07999 Arguments:
    08000
    08001     Apc - Supplies a pointer to kernel APC structure.
    08002
    08003     NormalRoutine - Supplies a pointer to a pointer to the normal function
    08004         that was specified when the APC was initialied.
    08005
    08006     NormalContext - Supplies a pointer to a pointer to an arbitrary data
    08007         structure that was specified when the APC was initialized.
    08008
    08009     SystemArgument1, SystemArgument2 - Supplies a set of two pointers to
    08010         two arguments that contain untyped data.
    08011
    08012 Return Value:
    08013
    08014     None.
    08015
    08016 Note:
    08017
    08018     If no other processing is ever needed, and the APC can be placed at the
    08019     beginning of the IRP, then this routine could be replaced by simply
    08020     specifying the address of the pool deallocation routine in the APC instead
    08021     of the address of this routine.
    08022
    08023 Caution:
    08024
    08025     This routine is also invoked as a general purpose rundown routine for APCs.
    08026     Should this code ever need to directly access any of the other parameters
    08027     other than Apc, this routine will need to be split into two separate
    08028     routines.  The rundown routine should perform exactly the following code's
    08029     functionality.
    08030
    08031 --*/
    08032
    08033 {
    08034     UNREFERENCED_PARAMETER( NormalRoutine );
    08035     UNREFERENCED_PARAMETER( NormalContext );
    08036     UNREFERENCED_PARAMETER( SystemArgument1 );
    08037     UNREFERENCED_PARAMETER( SystemArgument2 );
    08038
    08039     PAGED_CODE();
    08040
    08041     //
    08042     // Free the packet.
    08043     //
    08044
    08045     IoFreeIrp( CONTAINING_RECORD( Apc, IRP, Tail.Apc ) );
    08046 }

NTSTATUS IopXxxControlFile | ( | IN HANDLE | FileHandle,
|  | IN HANDLE Event | OPTIONAL,
|  | IN PIO_APC_ROUTINE ApcRoutine | OPTIONAL,
|  | IN PVOID ApcContext | OPTIONAL,
|  | OUT PIO_STATUS_BLOCK | IoStatusBlock,
|  | IN ULONG | IoControlCode,
|  | IN PVOID InputBuffer | OPTIONAL,
|  | IN ULONG | InputBufferLength,
|  | OUT PVOID OutputBuffer | OPTIONAL,
|  | IN ULONG | OutputBufferLength,
|  | IN BOOLEAN | DeviceIoControl
| ) |

Definition at line 8084 of file internal.c.

References _IRP::AssociatedIrp, _IRP::Cancel, _IRP::CancelRoutine, _DEVICE_OBJECT::DriverObject, Event(), ExAllocatePoolWithQuota, EXCEPTION_EXECUTE_HANDLER, ExEventObjectType, ExRaiseStatus(), FALSE, _FAST_IO_DISPATCH::FastIoDeviceControl, _DRIVER_OBJECT::FastIoDispatch, _IO_STACK_LOCATION::FileObject, _IRP::Flags, FO_ALERTABLE_IO, FO_DIRECT_DEVICE_OPEN, FO_SYNCHRONOUS_IO, _OBJECT_HANDLE_INFORMATION::GrantedAccess, IoAllocateMdl(), IoFileObjectType, IoGetAttachedDevice(), IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), IopAcquireFastLock, IopAcquireFileObjectLock(), IopAllocateIrp, IopAllocateIrpCleanup(), IopApcRoutinePresent, IopExceptionCleanup(), IopReleaseFileObjectLock, IopSynchronousServiceTail(), IoReadAccess, IoSetIoCompletion(), IoWriteAccess, IRP_BUFFERED_IO, IRP_DEALLOCATE_BUFFER, IRP_DEFER_IO_COMPLETION, IRP_INPUT_OPERATION, IRP_MJ_DEVICE_CONTROL, IRP_MJ_FILE_SYSTEM_CONTROL, KeClearEvent, KernelMode, KeSetEvent(), KPROCESSOR_MODE, L, LOCK_OPERATION, _IO_STACK_LOCATION::MajorFunction, _IRP::MdlAddress, MmProbeAndLockPages(), NonPagedPool, NonPagedPoolCacheAligned, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObjectByHandle(), OtherTransfer, _IRP::Overlay, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PDRIVER_CANCEL, _IRP::PendingReturned, POOL_TYPE, ProbeForRead, ProbeForWrite(), ProbeForWriteIoStatusEx, PsGetCurrentThread, _IRP::RequestorMode, SeComputeGrantedAccesses, _DEVICE_OBJECT::StackSize, _IRP::Tail, TRUE, _IRP::UserBuffer, _IRP::UserEvent, and _IRP::UserIosb.

Referenced by NtDeviceIoControlFile(), and NtFsControlFile().

    08100                    :
    08101
    08102     This service builds descriptors or MDLs for the supplied buffer(s) and
    08103     passes the untyped data to the driver associated with the file handle.
    08104     handle.  It is up to the driver to check the input data and function
    08105     IoControlCode for validity, as well as to make the appropriate access
    08106     checks.
    08107
    08108 Arguments:
    08109
    08110     FileHandle - Supplies a handle to the file on which the service is being
    08111         performed.
    08112
    08113     Event - Supplies an optional event to be set to the Signaled state when
    08114         the service is complete.
    08115
    08116     ApcRoutine - Supplies an optional APC routine to be executed when the
    08117         service is complete.
    08118
    08119     ApcContext - Supplies a context parameter to be passed to the ApcRoutine,
    08120         if an ApcRoutine was specified.
    08121
    08122     IoStatusBlock - Address of the caller's I/O status block.
    08123
    08124     IoControlCode - Subfunction code to determine exactly what operation is
    08125         being performed.
    08126
    08127     InputBuffer - Optionally supplies an input buffer to be passed to the
    08128         driver.  Whether or not the buffer is actually optional is dependent
    08129         on the IoControlCode.
    08130
    08131     InputBufferLength - Length of the InputBuffer in bytes.
    08132
    08133     OutputBuffer - Optionally supplies an output buffer to receive information
    08134         from the driver.  Whether or not the buffer is actually optional is
    08135         dependent on the IoControlCode.
    08136
    08137     OutputBufferLength - Length of the OutputBuffer in bytes.
    08138
    08139     DeviceIoControl - Determines whether this is a Device or File System
    08140         Control function.
    08141
    08142 Return Value:
    08143
    08144     The status returned is success if the control operation was properly
    08145     queued to the I/O system.   Once the operation completes, the status
    08146     can be determined by examining the Status field of the I/O status block.
    08147
    08148 --*/
    08149
    08150 {
    08151     PIRP irp;
    08152     NTSTATUS status;
    08153     PFILE_OBJECT fileObject;
    08154     PDEVICE_OBJECT deviceObject;
    08155     PKEVENT eventObject = (PKEVENT) NULL;
    08156     PIO_STACK_LOCATION irpSp;
    08157     ULONG method;
    08158     OBJECT_HANDLE_INFORMATION handleInformation;
    08159     BOOLEAN synchronousIo;
    08160     IO_STATUS_BLOCK localIoStatus;
    08161     PFAST_IO_DISPATCH fastIoDispatch;
    08162     POOL_TYPE poolType;
    08163     PULONG majorFunction;
    08164     KPROCESSOR_MODE requestorMode;
    08165
    08166     PAGED_CODE();
    08167
    08168     //
    08169     // Get the method that the buffers are being passed by.
    08170     //
    08171
    08172     method = IoControlCode & 3;
    08173
    08174     //
    08175     // Check the caller's parameters based on the mode of the caller.
    08176     //
    08177
    08178     requestorMode = KeGetPreviousMode();
    08179
    08180     if (requestorMode != KernelMode) {
    08181
    08182         //
    08183         // The caller's access mode is not kernel so probe each of the arguments
    08184         // and capture them as necessary.  If any failures occur, the condition
    08185         // handler will be invoked to handle them.  It will simply cleanup and
    08186         // return an access violation status code back to the system service
    08187         // dispatcher.
    08188         //
    08189
    08190         try {
    08191
    08192             //
    08193             // The IoStatusBlock parameter must be writeable by the caller.
    08194             //
    08195
    08196             ProbeForWriteIoStatusEx( IoStatusBlock , ApcRoutine);
    08197
    08198             //
    08199             // The output buffer can be used in any one of the following three ways,
    08200             // if it is specified:
    08201             //
    08202             //     0) It can be a normal, buffered output buffer.
    08203             //
    08204             //     1) It can be a DMA input buffer.
    08205             //
    08206             //     2) It can be a DMA output buffer.
    08207             //
    08208             // Which way the buffer is to be used it based on the low-order two bits
    08209             // of the IoControlCode.
    08210             //
    08211             // If the method is 0 we probe the output buffer for write access.
    08212             // If the method is not 3 we probe the input buffer for read access.
    08213             //
    08214
    08215             if (method == 0) {
    08216                 if (ARGUMENT_PRESENT( OutputBuffer )) {
    08217                     ProbeForWrite( OutputBuffer,
    08218                                    OutputBufferLength,
    08219                                    sizeof( UCHAR ) );
    08220                 } else {
    08221                     OutputBufferLength = 0;
    08222                 }
    08223             }
    08224
    08225             if (method != 3) {
    08226                 if (ARGUMENT_PRESENT( InputBuffer )) {
    08227                     ProbeForRead( InputBuffer,
    08228                                   InputBufferLength,
    08229                                   sizeof( UCHAR ) );
    08230                 } else {
    08231                     InputBufferLength = 0;
    08232                 }
    08233             }
    08234
    08235         } except(EXCEPTION_EXECUTE_HANDLER) {
    08236
    08237             //
    08238             // An exception was incurred while attempting to probe or write
    08239             // one of the caller's parameters.  Simply return an appropriate
    08240             // error status code.
    08241             //
    08242
    08243             return GetExceptionCode();
    08244
    08245         }
    08246     }
    08247
    08248     //
    08249     // There were no blatant errors so far, so reference the file object so
    08250     // the target device object can be found.  Note that if the handle does
    08251     // not refer to a file object, or if the caller does not have the required
    08252     // access to the file, then it will fail.
    08253     //
    08254
    08255     status = ObReferenceObjectByHandle( FileHandle,
    08256                                         0L,
    08257                                         IoFileObjectType,
    08258                                         requestorMode,
    08259                                         (PVOID *) &fileObject,
    08260                                         &handleInformation );
    08261     if (!NT_SUCCESS( status )) {
    08262         return status;
    08263     }
    08264
    08265     //
    08266     // If this file has an I/O completion port associated w/it, then ensure
    08267     // that the caller did not supply an APC routine, as the two are mutually
    08268     // exclusive methods for I/O completion notification.
    08269     //
    08270
    08271     if (fileObject->CompletionContext && IopApcRoutinePresent( ApcRoutine )) {
    08272         ObDereferenceObject( fileObject );
    08273         return STATUS_INVALID_PARAMETER;
    08274     }
    08275
    08276     //
    08277     // Now check the access type for this control code to ensure that the
    08278     // caller has the appropriate access to this file object to perform the
    08279     // operation.
    08280     //
    08281
    08282     if (requestorMode != KernelMode) {
    08283
    08284         ULONG accessMode = (IoControlCode >> 14) & 3;
    08285
    08286         if (accessMode != FILE_ANY_ACCESS) {
    08287
    08288             //
    08289             // This I/O control requires that the caller have read, write,
    08290             // or read/write access to the object.  If this is not the case,
    08291             // then cleanup and return an appropriate error status code.
    08292             //
    08293
    08294             if (SeComputeGrantedAccesses( handleInformation.GrantedAccess, accessMode ) != accessMode ) {
    08295                 ObDereferenceObject( fileObject );
    08296                 return STATUS_ACCESS_DENIED;
    08297             }
    08298         }
    08299     }
    08300
    08301     //
    08302     // Get the address of the event object and set the event to the Not-
    08303     // Signaled state, if an event was specified.  Note here, too, that if
    08304     // the handle does not refer to an event, or if the event cannot be
    08305     // written, then the reference will fail.
    08306     //
    08307
    08308     if (ARGUMENT_PRESENT( Event )) {
    08309         status = ObReferenceObjectByHandle( Event,
    08310                                             EVENT_MODIFY_STATE,
    08311                                             ExEventObjectType,
    08312                                             requestorMode,
    08313                                             (PVOID *) &eventObject,
    08314                                             NULL );
    08315         if (!NT_SUCCESS( status )) {
    08316             ObDereferenceObject( fileObject );
    08317             return status;
    08318         } else {
    08319             KeClearEvent( eventObject );
    08320         }
    08321     }
    08322
    08323     //
    08324     // Make a special check here to determine whether this is a synchronous
    08325     // I/O operation.  If it is, then wait here until the file is owned by
    08326     // the current thread.
    08327     //
    08328
    08329     if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
    08330         BOOLEAN interrupted;
    08331
    08332         if (!IopAcquireFastLock( fileObject )) {
    08333             status = IopAcquireFileObjectLock( fileObject,
    08334                                                requestorMode,
    08335                                                (BOOLEAN) ((fileObject->Flags & FO_ALERTABLE_IO) != 0),
    08336                                                &interrupted );
    08337             if (interrupted) {
    08338                 if (eventObject) {
    08339                     ObDereferenceObject( eventObject );
    08340                 }
    08341                 ObDereferenceObject( fileObject );
    08342                 return status;
    08343             }
    08344         }
    08345         synchronousIo = TRUE;
    08346     } else {
    08347         synchronousIo = FALSE;
    08348     }
    08349
    08350     //
    08351     // Get the address of the target device object.  If this file represents
    08352     // a device that was opened directly, then simply use the device or its
    08353     // attached device(s) directly.
    08354     //
    08355
    08356     if (!(fileObject->Flags & FO_DIRECT_DEVICE_OPEN)) {
    08357         deviceObject = IoGetRelatedDeviceObject( fileObject );
    08358     } else {
    08359         deviceObject = IoGetAttachedDevice( fileObject->DeviceObject );
    08360     }
    08361
    08362     if (DeviceIoControl) {
    08363
    08364         //
    08365         // Also get the address of the Fast I/O dispatch structure.
    08366         //
    08367
    08368         fastIoDispatch = deviceObject->DriverObject->FastIoDispatch;
    08369
    08370         //
    08371         // Turbo device control support.  If the device has a fast I/O entry
    08372         // point for DeviceIoControlFile, call the entry point and give it a
    08373         // chance to try to complete the request.  Note if FastIoDeviceControl
    08374         // returns FALSE or we get an I/O error, we simply fall through and
    08375         // go the "long way" and create an Irp.
    08376         //
    08377
    08378         if (fastIoDispatch && fastIoDispatch->FastIoDeviceControl) {
    08379
    08380             //
    08381             // Before we actually call the fast I/O routine in the driver,
    08382             // we must probe OutputBuffer if the method is 1 or 2.
    08383             //
    08384
    08385             if (requestorMode != KernelMode && ARGUMENT_PRESENT(OutputBuffer)) {
    08386
    08387                 try {
    08388
    08389                     if (method == 1) {
    08390                         ProbeForRead( OutputBuffer,
    08391                                       OutputBufferLength,
    08392                                       sizeof( UCHAR ) );
    08393                     } else if (method == 2) {
    08394                         ProbeForWrite( OutputBuffer,
    08395                                        OutputBufferLength,
    08396                                        sizeof( UCHAR ) );
    08397                     }
    08398
    08399                 } except(EXCEPTION_EXECUTE_HANDLER) {
    08400
    08401                     //
    08402                     // An exception was incurred while attempting to probe
    08403                     // the output buffer.  Clean up and return an
    08404                     // appropriate error status code.
    08405                     //
    08406
    08407                     if (synchronousIo) {
    08408                         IopReleaseFileObjectLock( fileObject );
    08409                     }
    08410
    08411                     if (eventObject) {
    08412                         ObDereferenceObject( eventObject );
    08413                     }
    08414
    08415                     ObDereferenceObject( fileObject );
    08416
    08417                     return GetExceptionCode();
    08418                 }
    08419             }
    08420
    08421             //
    08422             // Call the driver's fast I/O routine.
    08423             //
    08424
    08425             if (fastIoDispatch->FastIoDeviceControl( fileObject,
    08426                                                      TRUE,
    08427                                                      InputBuffer,
    08428                                                      InputBufferLength,
    08429                                                      OutputBuffer,
    08430                                                      OutputBufferLength,
    08431                                                      IoControlCode,
    08432                                                      &localIoStatus,
    08433                                                      deviceObject )) {
    08434
    08435                 //
    08436                 // The driver successfully performed the I/O in it's
    08437                 // fast device control routine.  Carefully return the
    08438                 // I/O status.
    08439                 //
    08440
    08441                 try {
    08442                     *IoStatusBlock = localIoStatus;
    08443                 } except( EXCEPTION_EXECUTE_HANDLER ) {
    08444                     localIoStatus.Status = GetExceptionCode();
    08445                     localIoStatus.Information = 0;
    08446                 }
    08447
    08448                 //
    08449                 // If an event was specified, set it.
    08450                 //
    08451
    08452                 if (ARGUMENT_PRESENT( Event )) {
    08453                     KeSetEvent( eventObject, 0, FALSE );
    08454                     ObDereferenceObject( eventObject );
    08455                 }
    08456
    08457                 //
    08458                 // Note that the file object event need not be set to the
    08459                 // Signaled state, as it is already set.  Release the
    08460                 // file object lock, if necessary.
    08461                 //
    08462
    08463                 if (synchronousIo) {
    08464                     IopReleaseFileObjectLock( fileObject );
    08465                 }
    08466
    08467                 //
    08468                 // If this file object has a completion port associated with it
    08469                 // and this request has a non-NULL APC context then a completion
    08470                 // message needs to be queued.
    08471                 //
    08472
    08473                 if (fileObject->CompletionContext && ARGUMENT_PRESENT( ApcContext )) {
    08474                     if (!NT_SUCCESS(IoSetIoCompletion( fileObject->CompletionContext->Port,
    08475                                                        fileObject->CompletionContext->Key,
    08476                                                        ApcContext,
    08477                                                        localIoStatus.Status,
    08478                                                        localIoStatus.Information,
    08479                                                        TRUE ))) {
    08480                         localIoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
    08481                     }
    08482                 }
    08483
    08484                 //
    08485                 // Cleanup and return.
    08486                 //
    08487
    08488                 ObDereferenceObject( fileObject );
    08489                 return localIoStatus.Status;
    08490             }
    08491         }
    08492
    08493     }
    08494
    08495     //
    08496     // Set the file object to the Not-Signaled state.
    08497     //
    08498
    08499     KeClearEvent( &fileObject->Event );
    08500
    08501     //
    08502     // Allocate and initialize the I/O Request Packet (IRP) for this operation.
    08503
    08504     irp = IopAllocateIrp( deviceObject->StackSize, TRUE );
    08505
    08506     if (!irp) {
    08507
    08508         //
    08509         // An IRP could not be allocated.  Cleanup and return an appropriate
    08510         // error status code.
    08511         //
    08512
    08513         IopAllocateIrpCleanup( fileObject, eventObject );
    08514
    08515         return STATUS_INSUFFICIENT_RESOURCES;
    08516     }
    08517     irp->Tail.Overlay.OriginalFileObject = fileObject;
    08518     irp->Tail.Overlay.Thread = PsGetCurrentThread();
    08519     irp->Tail.Overlay.AuxiliaryBuffer = (PVOID) NULL;
    08520     irp->RequestorMode = requestorMode;
    08521     irp->PendingReturned = FALSE;
    08522     irp->Cancel = FALSE;
    08523     irp->CancelRoutine = (PDRIVER_CANCEL) NULL;
    08524
    08525     //
    08526     // Fill in the service independent parameters in the IRP.
    08527     //
    08528
    08529     irp->UserEvent = eventObject;
    08530     irp->UserIosb = IoStatusBlock;
    08531     irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
    08532     irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
    08533
    08534     //
    08535     // Get a pointer to the stack location for the first driver.  This will be
    08536     // used to pass the original function codes and parameters.  Note that
    08537     // setting the major function here also sets:
    08538     //
    08539     //      MinorFunction = 0;
    08540     //      Flags = 0;
    08541     //      Control = 0;
    08542     //
    08543
    08544     irpSp = IoGetNextIrpStackLocation( irp );
    08545     majorFunction = (PULONG) (&irpSp->MajorFunction);
    08546     *majorFunction = DeviceIoControl ? IRP_MJ_DEVICE_CONTROL : IRP_MJ_FILE_SYSTEM_CONTROL;
    08547     irpSp->FileObject = fileObject;
    08548
    08549     //
    08550     // Copy the caller's parameters to the service-specific portion of the
    08551     // IRP for those parameters that are the same for all three methods.
    08552     //
    08553
    08554     irpSp->Parameters.DeviceIoControl.OutputBufferLength = OutputBufferLength;
    08555     irpSp->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
    08556     irpSp->Parameters.DeviceIoControl.IoControlCode = IoControlCode;
    08557
    08558     //
    08559     // Set the pool type based on the type of function being performed.
    08560     //
    08561
    08562     poolType = DeviceIoControl ? NonPagedPoolCacheAligned : NonPagedPool;
    08563
    08564     //
    08565     // Based on the method that the buffer are being passed, either allocate
    08566     // buffers or build MDLs.  Note that in some cases no probing has taken
    08567     // place so the exception handler must catch access violations.
    08568     //
    08569
    08570     irp->MdlAddress = (PMDL) NULL;
    08571     irp->AssociatedIrp.SystemBuffer = (PVOID) NULL;
    08572
    08573     switch ( method ) {
    08574
    08575     case 0:
    08576
    08577         //
    08578         // For this case, allocate a buffer that is large enough to contain
    08579         // both the input and the output buffers.  Copy the input buffer to
    08580         // the allocated buffer and set the appropriate IRP fields.
    08581         //
    08582
    08583         irpSp->Parameters.DeviceIoControl.Type3InputBuffer = (PVOID) NULL;
    08584
    08585         try {
    08586
    08587             if (InputBufferLength || OutputBufferLength) {
    08588                 irp->AssociatedIrp.SystemBuffer =
    08589                     ExAllocatePoolWithQuota( poolType,
    08590                                              (InputBufferLength > OutputBufferLength) ? InputBufferLength : OutputBufferLength );
    08591
    08592                 if (ARGUMENT_PRESENT( InputBuffer )) {
    08593                     RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
    08594                                    InputBuffer,
    08595                                    InputBufferLength );
    08596                 }
    08597                 irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
    08598                 irp->UserBuffer = OutputBuffer;
    08599                 if (ARGUMENT_PRESENT( OutputBuffer )) {
    08600                     irp->Flags |= IRP_INPUT_OPERATION;
    08601                 }
    08602             } else {
    08603                 irp->Flags = 0;
    08604                 irp->UserBuffer = (PVOID) NULL;
    08605             }
    08606
    08607         } except(EXCEPTION_EXECUTE_HANDLER) {
    08608
    08609             //
    08610             // An exception was incurred while either allocating the
    08611             // the system buffer or moving the caller's data.  Determine
    08612             // what actually happened, cleanup accordingly, and return
    08613             // an appropriate error status code.
    08614             //
    08615
    08616             IopExceptionCleanup( fileObject,
    08617                                  irp,
    08618                                  eventObject,
    08619                                  (PKEVENT) NULL );
    08620
    08621             return GetExceptionCode();
    08622         }
    08623
    08624         break;
    08625
    08626     case 1:
    08627     case 2:
    08628
    08629         //
    08630         // For these two cases, allocate a buffer that is large enough to
    08631         // contain the input buffer, if any, and copy the information to
    08632         // the allocated buffer.  Then build an MDL for either read or write
    08633         // access, depending on the method, for the output buffer.  Note
    08634         // that the buffer length parameters have been jammed to zero for
    08635         // users if the buffer parameter was not passed.  (Kernel callers
    08636         // should be calling the service correctly in the first place.)
    08637         //
    08638         // Note also that it doesn't make a whole lot of sense to specify
    08639         // either method #1 or #2 if the IOCTL does not require the caller
    08640         // to specify an output buffer.
    08641         //
    08642
    08643         irp->Flags = 0;
    08644         irpSp->Parameters.DeviceIoControl.Type3InputBuffer = (PVOID) NULL;
    08645
    08646         try {
    08647
    08648             if (InputBufferLength && ARGUMENT_PRESENT( InputBuffer )) {
    08649                 irp->AssociatedIrp.SystemBuffer =
    08650                     ExAllocatePoolWithQuota( poolType,
    08651                                              InputBufferLength );
    08652                 RtlCopyMemory( irp->AssociatedIrp.SystemBuffer,
    08653                                InputBuffer,
    08654                                InputBufferLength );
    08655                 irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
    08656             }
    08657
    08658             if (OutputBufferLength != 0) {
    08659                 irp->MdlAddress = IoAllocateMdl( OutputBuffer,
    08660                                                  OutputBufferLength,
    08661                                                  FALSE,
    08662                                                  TRUE,
    08663                                                  irp  );
    08664                 if (irp->MdlAddress == NULL) {
    08665                     ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
    08666                 }
    08667                 MmProbeAndLockPages( irp->MdlAddress,
    08668                                      requestorMode,
    08669                                      (LOCK_OPERATION) ((method == 1) ? IoReadAccess : IoWriteAccess) );
    08670             }
    08671
    08672         } except(EXCEPTION_EXECUTE_HANDLER) {
    08673
    08674             //
    08675             // An exception was incurred while either allocating the
    08676             // system buffer, copying the caller's data, allocating the
    08677             // MDL, or probing and locking the caller's buffer. Determine
    08678             // what actually happened, cleanup accordingly, and return
    08679             // an appropriate error status code.
    08680             //
    08681
    08682             IopExceptionCleanup( fileObject,
    08683                                  irp,
    08684                                  eventObject,
    08685                                  (PKEVENT) NULL );
    08686
    08687             return GetExceptionCode();
    08688         }
    08689
    08690         break;
    08691
    08692     case 3:
    08693
    08694         //
    08695         // For this case, do nothing.  Everything is up to the driver.
    08696         // Simply give the driver a copy of the caller's parameters and
    08697         // let the driver do everything itself.
    08698         //
    08699
    08700         irp->Flags = 0;
    08701         irp->UserBuffer = OutputBuffer;
    08702         irpSp->Parameters.DeviceIoControl.Type3InputBuffer = InputBuffer;
    08703     }
    08704
    08705     //
    08706     // Defer I/O completion for FSCTL requests, but not for IOCTL requests,
    08707     // since file systems set pending properly but device driver do not.
    08708     //
    08709
    08710     if (!DeviceIoControl) {
    08711         irp->Flags |= IRP_DEFER_IO_COMPLETION;
    08712     }
    08713
    08714     //
    08715     // Queue the packet, call the driver, and synchronize appropriately with
    08716     // I/O completion.
    08717     //
    08718
    08719     return IopSynchronousServiceTail( deviceObject,
    08720                                       irp,
    08721                                       fileObject,
    08722                                       (BOOLEAN)!DeviceIoControl,
    08723                                       requestorMode,
    08724                                       synchronousIo,
    08725                                       OtherTransfer );
    08726 }

typedef NTSTATUS | ( | FASTCALL * | PIO_CALL_DRIVER | ) |

| Referenced by __ClientLoadOLE(), __declspec(), _BuildNameList(), _BuildPropList(), _EndTask(), _ExitWindowsEx(), _GetUserObjectInformation(), _ImpersonateDdeClientWindow(), _OpenWindowStation(), _SetUserObjectInformation(), _UserTestForWinStaAccess(), _UserTestTokenForInteractive(), AccessCheckObject(), AllocateCallbackData(), AllocateConsole(), AllocateConsoleHandle(), AllocateIoHandle(), AllocCallbackMessage(), AllocConsoleInternal(), ApiPreamble(), ArbAddAllocation(), ArbAllocateEntry(), ArbArbiterHandler(), ArbBacktrackAllocation(), ArbBootAllocation(), ArbBuildAssignmentOrdering(), ArbFindSuitableRange(), ArbInitializeArbiterInstance(), ArbpBuildAllocationStack(), ArbpBuildAlternative(), ArbpGetRegistryValue(), ArbPruneOrdering(), ArbQueryConflict(), ArbRetestAllocation(), ArbTestAllocation(), bCheckAndDeleteTTF(), bCleanConvertedTTFs(), bLoadableFontDrivers(), BrokenConnection(), BuildHimcList(), BuildHwndList(), BuildQueryDirectoryIrp(), CallUserpRegisterLogonProcess(), CaptureAnsiCallbackData(), CaptureCallbackData(), CaptureUnicodeCallbackData(), CcCopyRead(), CcCopyReadExceptionFilter(), CcCopyWrite(), CcFastCopyRead(), CcFastCopyWrite(), CcFlushCache(), CcGetDirtyPages(), CcGetVacbMiss(), CcInitializeCacheMap(), CcLogError(), CcMapAndCopy(), CcMdlWriteComplete2(), CcSetFileSizes(), CcSetValidData(), CcWriteBehind(), CcZeroData(), CdfsRecFsControl(), ChangeMemberState(), CharLowerA(), CharUpperA(), CheckAllowForeground(), CheckClipboardAccess(), CheckDesktopPolicy(), CheckRestricted(), CleanupSessionObjectDirectories(), ClientThread(), ClientThreadSetup(), CliGetImeHotKeysFromRegistry(), CliReadRegistryValue(), CliSetSingleHotKey(), CloseDevice(), CloseOutputHandle(), CmDeleteKey(), CmDeleteKeyRecursive(), CmDeleteValueKey(), CmEnumerateKey(), CmEnumerateValueKey(), CmFlushKey(), CmGetSystemControlValues(), CmGetSystemDriverList(), CmInitSystem1(), CmLoadKey(), CmpAddAcpiAliasEntry(), CmpAddAliasEntry(), CmpAddDockingInfo(), CmpAddDriverToList(), CmpAddToHiveFileList(), CmpAppendStringToMultiSz(), CmpCacheLookup(), CmpCheckNotifyAccess(), CmpCloneControlSet(), CmpCloneHwProfile(), CmpCopyKeyPartial(), CmpCreateControlSet(), CmpCreateEvent(), CmpCreateHwProfileFriendlyName(), CmpCreateLinkNode(), CmpCreateObjectTypes(), CmpCreatePerfKeys(), CmpCreatePredefined(), CmpCreateRegistryRoot(), CmpCreateTemporaryHive(), CmpDestroyHive(), CmpDiskFullWarningWorker(), CmpDoCreate(), CmpDoCreateChild(), CmpDoFileSetSize(), CmpDoFlushAll(), CmpDoOpen(), CmpFileFlush(), CmpFileRead(), CmpFileSetSize(), CmpFileWrite(), CmpFilterAcpiDockingState(), CmpFindACPITable(), CmpFindControlSet(), CmpFindMatchingDescriptorCell(), CmpFindNameInList(), CmpFindNLSData(), CmpFindRSDTTable(), CmpFindTagIndex(), CmpFindValueByNameFromCache(), CmpGetAcpiProfileInformation(), CmpGetAddRegInfData(), CmpGetRegistryValue(), CmpGetSymbolicLink(), CmpHiveRootSecurityDescriptor(), CmpInitHiveFromFile(), CmpInitializeHardwareConfiguration(), CmpInitializeHive(), CmpInitializeHiveList(), CmpInitializeMachineDependentConfiguration(), CmpInitializeRegistryNode(), CmpInitializeSystemHive(), CmpInterlockedFunction(), CmpIsLastKnownGoodBoot(), CmpIsLoadType(), CmpLinkHiveToMaster(), CmpLinkKeyToHive(), CmpLoadHiveVolatile(), CmpMapPhysicalAddress(), CmpMergeKeyValues(), CmpMoveBiosAliasTable(), CmpNameFromAttributes(), CmpOpenFileWithExtremePrejudice(), CmpOpenHiveFiles(), CmpOpenRegKey(), CmpParseKey(), CmpProcessAddRegLine(), CmpProcessBitRegLine(), CmpProcessDelRegLine(), CmpProcessReg(), CmpQueryKeyData(), CmpQueryKeyName(), CmpQueryKeyValueData(), CmpQuerySecurityDescriptorInfo(), CmpQuotaWarningWorker(), CmpRemoveFromHiveFileList(), CmpSaveBootControlSet(), CmpSaveKeyByFileCopy(), CmpSecurityMethod(), CmpSetSecurityDescriptorInfo(), CmpSetupConfigurationTree(), CmpSetVersionData(), CmpSortDriverList(), CmpSyncKeyValues(), CmpValidateAlternate(), CmpWalkPath(), CmpWorker(), CmQueryKey(), CmQueryMultipleValueKey(), CmQueryValueKey(), CmReplaceKey(), CmRestoreKey(), CmSaveKey(), CmSaveMergedKeys(), CmSetAcpiHwProfile(), CmSetLastWriteTimeKey(), CmSetValueKey(), CommandNumberPopup(), CommitReadOnlyMemory(), CommonCreateWindowStation(), CommonOpenWindowStation(), ComPortDBAdd(), ConDllInitialize(), ConnectConsoleInternal(), ConnectToEmulator(), ConnectToTerminalServer(), ConServerDllInitialization(), ConsoleAddProcessRoutine(), ConsoleClientConnectRoutine(), ConsoleClientShutdown(), ConsoleInputThread(), ConvertInputToUnicode(), ConvertOutputToOem(), ConvertOutputToUnicode(), ConvertToFullScreen(), ConvertToOem(), ConvertToWindowed(), CookedRead(), CookedReadWaitRoutine(), Copy(), CopyFromCharPopup(), CopyRestrictedFile(), CopyStream(), CopyToCharPopup(), CreateBSMEventSD(), CreateConsoleBitmap(), CreateCtrlThread(), CreateDAclToken(), CreateDesktopA(), CreateDesktopHeap(), CreateDirectories(), CreateFtMember(), CreateGlobalAtomTable(), CreateInputBuffer(), CreateLocalMemHandle(), CreateScreenBuffer(), CreateSecurityDescriptor(), CreateSystemThread(), CsrClientCallServer(), CsrClientConnectToServer(), CsrIdentifyAlertableThread(), CsrOneTimeInitialize(), CsrpConnectToServer(), CsrSetPriorityClass(), CtxUserGetWinstationInfo(), DbgkCreateThread(), DbgkForwardException(), DbgkpSectionHandleToFileHandle(), DbgkpSendApiMessage(), DbgPrint(), DbgSsHandleKmApiMsg(), DbgSsInitialize(), DbgSspConnectToDbg(), DbgSspCreateProcess(), DbgSspCreateThread(), DbgSspException(), DbgSspExitProcess(), DbgSspExitThread(), DbgSspLoadDll(), DbgSspSrvApiLoop(), DbgSspUnloadDll(), DbgUiConnectToDbg(), DbgUiContinue(), DbgUiWaitStateChange(), DebugService(), Delete(), DeviceCDROMNotify(), DeviceClassCDROMNotify(), DeviceNotify(), Directory(), DirectReadWaitRoutine(), DisableAllPrivileges(), DiskDump(), DisplayModeTransition(), DisplaySecurityContext(), DoCreateScreenBuffer(), DoEventTest(), DoExceptionTest(), DoInfoTest(), DoLuidTest(), DoMutantTest(), DoPartyTest(), DoSemaphoreTest(), DoTest(), DoTimerTest(), DoZoneTest(), DrChangeDisplaySettings(), DrGetDeviceName(), DriverEntry(), DrSetDevMode(), Dump(), DumpKeys(), DumpObjectDirs(), DumpSecurity(), DumpValues(), EhCreateChild(), EhOpenHive(), EhpAttachSecurity(), EisaBuildEisaDeviceNode(), EisaGetEisaDevicesResources(), EnableAllPrivileges(), EndShutdown(), EnterHandleFlagsCrit(), EnumDisplayDevices(), ExAllocatePool(), ExceptionTest(), ExCreateCallback(), ExInterlockedExtendZone(), ExitWindowsWorker(), ExpAllocateUuids(), ExpCreateWorkerThread(), ExpDetectWorkerThreadDeadlock(), ExpEventInitialization(), ExpEventPairInitialization(), ExpGetCurrentUserUILanguage(), ExpGetHandleInformation(), ExpGetLockInformation(), ExpGetLookasideInformation(), ExpGetObjectInformation(), ExpGetPoolInformation(), ExpGetPoolTagInfo(), ExpGetProcessInformation(), ExpGetUILanguagePolicy(), ExpInitializeCallbacks(), ExpMutantInitialization(), ExpProfileInitialization(), ExpQueryLegacyDriverInformation(), ExpQueryModuleInformation(), ExpRaiseException(), ExpRaiseHardError(), ExpRaiseStatus(), ExpSemaphoreInitialization(), ExpSetCurrentUserUILanguage(), ExpSystemErrorHandler(), ExpTimerInitialization(), ExpUuidGetValues(), ExpUuidInitialization(), ExpUuidLoadSequenceNumber(), ExpUuidSaveSequenceNumber(), ExpUuidSaveSequenceNumberIf(), ExpValidateLocale(), ExpWaitForResource(), ExpWaitForResourceDdk(), ExpWin32Initialization(), ExpWorkerInitialization(), ExpWorkerThreadBalanceManager(), ExQuerySystemLockInformation(), ExRaiseHardError(), ExRegisterCallback(), ExSnapShotHandleTables(), ExUuidCreate(), FalseUnicodeToRealUnicode(), FatRecFsControl(), FE_WriteRegionToScreenHW(), FileExists(), FindActiveScreenBufferHandle(), FindPathForDevice(), FixDisk(), FlushAllButKeys(), FreeDesktop(), FreeIoHandle(), FreeView(), FsgWriteToFrameBuffer(), FsRecCreate(), FsRecCreateAndRegisterDO(), FsRecFsControl(), FsRecGetDeviceSectors(), FsRecGetDeviceSectorSize(), FsRecLoadFileSystem(), FsRecReadBlock(), FsRtlAcknowledgeOplockBreak(), FsRtlAcquireFileForCcFlush(), FsRtlAcquireFileForModWrite(), FsRtlAreNamesEqual(), FsRtlBalanceReads(), FsRtlCheckOplock(), FsRtlCompleteLockIrpReal(), FsRtlDeregisterUncProvider(), FsRtlFastUnlockSingle(), FsRtlGetCompatibilityModeValue(), FsRtlGetFileSize(), FsRtlGetTunnelParameterValue(), FsRtlIsNameInExpression(), FsRtlNotifyVolumeEvent(), FsRtlOpBatchBreakClosePending(), FsRtlOplockBreakNotify(), FsRtlOplockBreakToII(), FsRtlOplockBreakToNone(), FsRtlOplockFsctrl(), FsRtlpIsDfsEnabled(), FsRtlpOpenDev(), FsRtlpRegisterProviderWithMUP(), FsRtlPrivateCancelFileLockIrp(), FsRtlPrivateCheckWaitingLocks(), FsRtlPrivateFastUnlockAll(), FsRtlPrivateLock(), FsRtlPrivateRemoveLock(), FsRtlProcessFileLock(), FsRtlpSetSymbolicLink(), FsRtlRegisterUncProvider(), FsRtlReleaseFileForCcFlush(), FsRtlReleaseFileForModWrite(), FsRtlRequestExclusiveOplock(), FsRtlRequestOplockII(), FsRtlSetFileSize(), FsRtlSyncVolumes(), FsRtlUninitializeFileLock(), FsRtlWaitOnIrp(), FstubTranslateResource(), FsVgaConfiguration(), FsVgaDeviceControl(), FsVgaPeripheralCallout(), FsVgaServiceParameters(), FtCreateKey(), FtDeleteKey(), FtDeleteValue(), FtOpenKey(), FtReturnValue(), FtSetValue(), GenerateDescriptor(), GetActiveKeyboardName(), GetBadAppCmdLine(), GetChar(), GetConsoleInputExeNameA(), GetConsoleLangId(), GetDeviceChangeInfo(), GetDiskInfo(), GetHardErrorText(), GetMySid(), GetNextReparseVolumePath(), GetProcessLuid(), GetRealDllFileNameWorker(), GetRegIntFromID(), GetRegistryValues(), GetServerIMEKeyboardLayout(), GetSiteSidFromToken(), GetTaskName(), GetThreadConsoleDesktop(), GetTimeouts(), GetUserObjectSecurity(), GetVersionInfo(), HalpEnableAutomaticDriveLetterAssignment(), HalpGetFullGeometry(), HalpIsOldStyleFloppy(), HalpNextDriveLetter(), HalpNextMountLetter(), HalpQueryDriveLayout(), HalpQueryPartitionType(), HalpSetMountLetter(), HandleMediaChangeEvent(), HMGrowHandleTable(), HMInitHandleTable(), HvInitializeHive(), HvLoadHive(), HvpBuildMap(), HvpBuildMapAndCopy(), HvpEnlistBinInMap(), HvpInitMap(), HvpReadFileImageAndBuildMap(), HvWriteHive(), ImmLoadLayout(), InheritIoHandleTable(), InitCreateObjectDirectory(), InitCreateSharedSection(), InitializeClientPfnArrays(), InitializeConsoleHandleTable(), InitializeInputHandle(), InitializeIoHandleTable(), InitializePowerRequestList(), InitializeRestrictedStuff(), InitializeScrollBuffer(), InitiateShutdown(), InitiateWin32kCleanup(), InitMapSharedSection(), InitSystemThread(), InitTask(), InitWindowsStuff(), InputExceptionFilter(), InternalCreateCallbackThread(), InternalEnumObjects(), InternalEnumProps(), IoAcquireRemoveLockEx(), IoAsynchronousPageWrite(), IoAttachDevice(), IoAttachDeviceByPointer(), IoCancelFileOpen(), IoCheckFunctionAccess(), IoConnectInterrupt(), IoCreateController(), IoCreateDevice(), IoCreateDriver(), IoCreateFile(), IoCreateNotificationEvent(), IoCreateStreamFileObject(), IoCreateStreamFileObjectLite(), IoCreateSymbolicLink(), IoCreateSynchronizationEvent(), IoCreateUnprotectedSymbolicLink(), IoDeleteSymbolicLink(), IoepCatMsgArg(), IoepExtractErrData(), IoepFireWMIEvent(), IoepGetErrCaseDB(), IoepGetErrMessage(), IoepHandleErrCase(), IoepUnicodeStringCatN(), IoErrFindErrCaseByID(), IoErrGetErrData(), IoErrGetLongErrMessage(), IoErrGetShortErrMessage(), IoErrHandleErrCase(), IoErrMatchErrCase(), IoErrRegisterErrHandlers(), IoErrRetrieveSavedData(), IoFastQueryNetworkAttributes(), IoFreeDumpStack(), IoGetBootDiskInformation(), IoGetDeviceInterfaceAlias(), IoGetDeviceInterfaces(), IoGetDeviceObjectPointer(), IoGetDeviceProperty(), IoGetDmaAdapter(), IoGetLegacyVetoList(), IoGetRelatedTargetDevice(), IoInitializeDumpStack(), IoInitSystem(), IoIsValidNameGraftingBuffer(), IoOpenDeviceInterfaceRegistryKey(), IoOpenDeviceRegistryKey(), IopAcquireFileObjectLock(), IopAddDevicesToBootDriver(), IopAddDevicesToBootDriverWorker(), IopAddRemoteBootValuesToRegistry(), IoPageFileCreated(), IopAllocateBootResources(), IopAllocateErrorLogEntry(), IopAllocateResources(), IopAppendBuffer(), IopAppendStringToValueKey(), IopApplyFunctionToServiceInstances(), IopApplyFunctionToSubKeys(), IopApplySystemPartitionProt(), IopArbitrateDeviceResources(), IopAssign(), IopAssignInner(), IopAssignNetworkDriveLetter(), IopAssignResourcesToDevices(), IopAsynchronousCall(), IopBootLog(), IopBootLogToFile(), IopBuildCmResourceList(), IopBuildCmResourceLists(), IopBuildSymbolicLinkStrings(), IopBusCheck(), IopBusNumberInitialize(), IopCacheNetbiosNameForIpAddress(), IopCallArbiter(), IopCallDriverAddDevice(), IopCallDriverAddDeviceQueryRoutine(), IopCaptureObjectName(), IopChainDereferenceComplete(), IopChangeDeviceObjectFromRegistryProperties(), IopCheckDeviceAndDriver(), IopChildToRootTranslation(), IopCleanupDeviceRegistryValues(), IopCloseFile(), IopCombineLegacyResources(), IopCompleteDumpInitialization(), IopCompleteRequest(), IopConnectLinkTrackingPort(), IopCopyBootLogRegistryToFile(), IopCreateArcNames(), IopCreateDefaultDeviceSecurityDescriptor(), IopCreateMadeupNode(), IopCreateRegistryKeyEx(), IopCreateRootDirectories(), IopDeleteFile(), IopDeleteKeyRecursive(), IopDeleteKeyRecursiveCallback(), IopDeleteLegacyKey(), IopDeleteLockedDeviceNode(), IopDeleteLockedDeviceNodes(), IopDeleteSessionSymLinks(), IopDetermineDefaultInterfaceType(), IopDeviceActionWorker(), IopDeviceCapabilitiesToRegistry(), IopDeviceInterfaceKeysFromSymbolicLink(), IopDeviceNodeCapabilitiesToRegistry(), IopDeviceObjectFromDeviceInstance(), IopDeviceObjectToDeviceInstance(), IopDisableDevice(), IopDisassociateThreadIrp(), IopDriverCorrectnessCheckUnderLock(), IopDriverLoadingFailed(), IopDropReferenceString(), IopDuplicateDetection(), IopEjectDevice(), IopEliminateBogusConflict(), IopEnumerateDevice(), IopErrorLogConnectPort(), IopErrorLogThread(), IopExecuteHardwareProfileChange(), IopfCallDriver(), IopFilterResourceRequirementsCall(), IopFilterResourceRequirementsList(), IopFindLegacyDeviceNode(), IopForAllChildDeviceNodes(), IopForAllDeviceNodes(), IopForAllDeviceNodesCallback(), IopFreeDCB(), IopGenericTranslateOrdering(), IopGetDeviceInstanceCsConfigFlags(), IopGetDeviceInterfaces(), IopGetDeviceResourcesFromRegistry(), IopGetDriverDeviceList(), IopGetDriverNameFromKeyNode(), IopGetDriverTagPriority(), IopGetDumpStack(), IopGetFileName(), IopGetGroupOrderIndex(), IopGetLegacyVetoListDrivers(), IopGetRegistryDwordWithFallback(), IopGetRegistryKeyInformation(), IopGetRegistrySecurityWithFallback(), IopGetRegistryValue(), IopGetRegistryValues(), IopGetRelatedTargetDevice(), IopGetResourceRequirementsForAssignTable(), IopGetRootDevices(), IopGetServiceInstanceCsConfigFlags(), IopGetServiceType(), IopGetSetObjectId(), IopGetSetSecurityObject(), IopGetVolumeId(), IopHardwareProfileBeginTransition(), IopHardwareProfileCancelRemovedDock(), IopHardwareProfileCommitRemovedDock(), IopHardwareProfileCommitStartedDock(), IopHardwareProfileMarkDock(), IopHardwareProfileQueryChange(), IopHardwareProfileSendCancel(), IopInitializeAttributesAndCreateObject(), IopInitializeBootDrivers(), IopInitializeBootLogging(), IopInitializeBuiltinDriver(), IopInitializeDCB(), IopInitializeDeviceInstanceKey(), IopInitializePlugPlayServices(), IopInitializeResourceMap(), IopInitializeSystemDrivers(), IopInvalidateVolumesForDevice(), IopIsAnyDeviceInstanceEnabled(), IopIsDeviceInstanceEnabled(), IopIsFirmwareDisabled(), IopIsFirmwareMapperDevicePresent(), IopIsReportedAlready(), IopIsSameMachine(), IopLegacyResourceAllocation(), IopLoadBootFilterDriver(), IopLoadDriver(), IopLoadDumpDriver(), IopLoadFileSystemDriver(), IopLoadUnloadDriver(), IopLockDeviceRemovalRelations(), IopLookupBusStringFromID(), IopMakeGloballyUniqueId(), IopMarkBootPartition(), IopMarkDuplicateDevice(), IopMemInitialize(), IopMergeCmResourceLists(), IopMergeFilteredResourceRequirementsList(), IopMergeRelationLists(), IopMountVolume(), IopNewDevice(), IopNotifyDeviceClassChange(), IopNotifyHwProfileChange(), IopNotifySetupDeviceArrival(), IopNotifySetupDevices(), IopNotifyTargetDeviceChange(), IoPnPDeliverServicePowerNotification(), IopOpenCurrentHwProfileDeviceInstanceKey(), IopOpenDeviceParametersSubkey(), IopOpenLinkOrRenameTarget(), IopOpenOrCreateDeviceInterfaceSubKeys(), IopOpenRegistryKeyPersist(), IopOpenServiceEnumKeys(), IopOverwriteBuffer(), IopParentToRawTranslation(), IopParseDevice(), IopParseSymbolicLinkName(), IopPlacement(), IopPlacementForRebalance(), IopPlacementForReservation(), IopPnPDispatch(), IopPnPHydraCallback(), IopPortAddAllocation(), IopPortBacktrackAllocation(), IopPortFindSuitableRange(), IopPortIsAliasedRangeAvailable(), IopPowerDispatch(), IopPrepareDriverLoading(), IopProcessCompletedEject(), IopProcessCriticalDevice(), IopProcessCriticalDeviceRoutine(), IopProcessNewChildren(), IopProcessNewDeviceNode(), IopProcessRelation(), IopProcessSetInterfaceState(), IopProcessStartDevices(), IopProcessStartDevicesWorker(), IopProtectSystemPartition(), IopQueryCompatibleIds(), IopQueryConflictFillConflicts(), IopQueryConflictFillString(), IopQueryConflictList(), IopQueryConflictListInternal(), IopQueryDeviceCapabilities(), IopQueryDeviceId(), IopQueryDeviceRelations(), IopQueryDeviceResources(), IopQueryDeviceSerialNumber(), IopQueryDeviceState(), IopQueryDockRemovalInterface(), IopQueryLegacyBusInformation(), IopQueryName(), IopQueryPnpBusInformation(), IopQueryReconfiguration(), IopQueryResourceHandlerInterface(), IopQueryUniqueId(), IopQueryXxxInformation(), IopRaiseHardError(), IopReadDeviceConfiguration(), IopReadDumpRegistry(), IopReallocateResources(), IopReassignSystemRoot(), IopRebalance(), IopReferenceDriverObjectByName(), IopRegisterDeviceInterface(), IopReleaseDeviceResources(), IopReleaseFilteredBootResources(), IopReleaseResourcesInternal(), IopRemoveDevice(), IopRemoveDeviceInterfaces(), IopRemoveStringFromValueKey(), IopRequestHwProfileChangeNotification(), IopReserve(), IopReserveBootResources(), IopReserveBootResourcesInternal(), IopReserveLegacyBootResources(), IopResourceRequirementsListToReqList(), IopRestoreResourcesInternal(), IopSafebootDriverLoad(), IopSendMessageToTrackService(), IopServiceInstanceToDeviceInstance(), IopSetDefaultGateway(), IopSetDeviceInstanceCsConfigFlags(), IopSetDeviceSecurityDescriptors(), IopSetEaOrQuotaInformationFile(), IopSetLegacyDeviceInstance(), IopSetRegistryStringValue(), IopSetRemoteLink(), IopSetSecurityObjectFromRegistry(), IopSetServiceInstanceCsConfigFlags(), IopSetupArbiterAndTranslators(), IopSetupRemoteBootCard(), IopStartAndEnumerateDevice(), IopStartApcHardError(), IopStartDevice(), IopStartDriverDevices(), IopStartNetworkForRemoteBoot(), IopStartTcpIpForRemoteBoot(), IopStoreSystemPartitionInformation(), IopSynchronousApiServiceTail(), IopSynchronousCall(), IopSynchronousServiceTail(), IopTCPQueryInformationEx(), IopTCPSetInformationEx(), IopTestForReconfiguration(), IopTrackLink(), IopTranslateAndAdjustReqDesc(), IopTranslateBusAddress(), IopUnloadAttachedDriver(), IopUnlockDeviceRemovalRelations(), IopUnregisterDeviceInterface(), IopUpdateHardwareProfile(), IopWaitForBootDevicesDeleted(), IopWaitForBootDevicesStarted(), IopWarmEjectDevice(), IopWriteAllocatedResourcesToRegistry(), IopWriteIpAddressToRegistry(), IopWritePageToDisk(), IopWriteResourceList(), IopWriteSummaryDump(), IopWriteSummaryHeader(), IopWriteTriageDump(), IopXxxControlFile(), IoQueryDeviceDescription(), IoRegisterDeviceInterface(), IoRegisterPlugPlayNotification(), IoReportDetectedDevice(), IoReportHalResourceUsage(), IoReportResourceUsageInternal(), IoReportTargetDeviceChange(), IoReportTargetDeviceChangeAsynchronous(), IoSetCrashDumpState(), IoSetDeviceInterfaceState(), IoSetInformation(), IoSetIoCompletion(), IoSynchronousInvalidateDeviceRelations(), IovCallDriver(), IoVerifyVolume(), IovInitializeTimer(), IovpAssertIrpStackDownward(), IovpAssertIrpStackUpward(), IovpAssertNewRequest(), IovpCallDriver2(), IovpCompleteRequest2(), IovpCompleteRequest5(), IovpInternalCompleteAfterWait(), IovpSessionDataFinalizeSurrogate(), IovpSwapSurrogateIrp(), IovpThrowBogusSynchronousIrp(), IovpThrowChaffAtStartedPdoStack(), IovSpecialIrpCallDriver(), IoWriteCrashDump(), IsInterestingPath(), IsPrivileged(), IsTokenRestricted(), KbdLayerRealDllFileForWBT(), KdpSendWaitContinue(), Ke386CallBios(), KeBalanceSetManager(), KeDelayExecutionThread(), KeI386GetLid(), KeI386ReleaseLid(), KeI386VdmInitialize(), KeQueryIntervalProfile(), KeRaiseUserException(), KeRemoveQueue(), KeSetEvent(), KeSetup80387OrEmulate(), KeSwapProcessOrStack(), KeUserModeCallback(), KeWaitForMultipleObjects(), KeWaitForSingleObject(), Ki386CheckDivideByZeroTrap(), KiAmdK6MtrrSetMemoryType(), KiContinue(), KiInitializeMTRR(), KiInitMachineDependent(), KillProcess(), KiMemoryFault(), KiMoveRegTree(), KiWaitTest(), LdrAlternateResourcesEnabled(), LdrDisableThreadCalloutsForDll(), LdrEnumResources(), LdrGetDllHandle(), LdrLoadAlternateResourceModule(), LdrpAccessResourceData(), LdrpCheckForKnownDll(), LdrpCheckForLoadedDll(), LdrpCreateDllSection(), LdrpDphSnapImports(), LdrpForkProcess(), LdrpGetFileVersion(), LdrpGetProcedureAddress(), LdrpInitializationFailure(), LdrpInitialize(), LdrpInitializeProcess(), LdrpLoadDll(), LdrpLoadImportModule(), LdrpMapDll(), LdrpRunInitializeRoutines(), LdrpSearchResourceSection_U(), LdrpSetProtection(), LdrpSnapIAT(), LdrpSnapThunk(), LdrpUpdateLoadCount(), LdrpVerifyAlternateResourceModule(), LdrpWalkImportDescriptor(), LdrQueryApplicationCompatibilityGoo(), LdrQueryImageFileExecutionOptions(), LdrQueryProcessModuleInformation(), LdrUnloadDll(), LdrVerifyImageMatchesChecksum(), LfsCloseLogFile(), LfsExceptionFilter(), LfsFindLastLsn(), LfsFlushLfcb(), LfsFlushToLsn(), LfsForceWrite(), LfsInitializeLogFile(), LfsOpenLogFile(), LfsPinOrMapData(), LfsReadLogRecord(), LfsReadNextLogRecord(), LfsReadRestart(), LfsReadRestartArea(), LfsSetBaseLsn(), LfsWrite(), LfsWriteRestartArea(), List(), ListDrivers(), LoadAppDlls(), LoadOLEOnce(), LockProcessByClientId(), LpcInitSystem(), LpcpAllocateFromPortZone(), LpcpCopyRequestData(), LpcpCreatePort(), LpcpExtendPortZone(), LpcpGetCreatorName(), LpcpInitializePortZone(), LpcRequestWaitReplyPort(), main(), MakeCursorVisible(), MapDesktop(), MapperConstructRootEnumTree(), MapperMarkKey(), MapperPhantomizeDetectedComPorts(), MapperSeedKey(), MapViewOfSection(), MatchandCopyAlias(), MemPrintInitialize(), MemPrintWriteThread(), MESSAGECALL(), MiAttemptPageFileExtension(), MiAttemptPageFileReduction(), MiCallDllUnloadAndUnloadDll(), MiCheckForCrashDump(), MiCheckForUserStackOverflow(), MiCheckPageFilePath(), MiCheckPdeForPagedPool(), MiCheckSecuredVad(), MiCleanSection(), MiCloneProcessAddressSpace(), MiCreateDataFileMap(), MiCreateImageFileMap(), MiDereferenceSegmentThread(), MiDispatchFault(), MiEmptyWorkingSet(), MiEnsureAvailablePageOrWait(), MiFlushSectionInternal(), MiGatherPagefilePages(), MiGetWorkingSetInfo(), MiGetWritablePagesInSection(), MiIssuePageExtendRequest(), MiIssuePageExtendRequestNoWait(), MiLoadImageSection(), MiLoadSystemImage(), MiMakeOutswappedPageResident(), MiMakeSystemAddressValid(), MiMakeSystemAddressValidPfn(), MiMakeSystemAddressValidPfnSystemWs(), MiMakeSystemAddressValidPfnWs(), MiMapCacheExceptionFilter(), MiMappedPageWriter(), MiMapViewOfImageSection(), MiModifiedPageWriterWorker(), MiProtectVirtualMemory(), MiReloadBootLoadedDrivers(), MiRemoveImageSessionWide(), MiRemoveUnusedSegments(), MiResolveImageReferences(), MiResolveProtoPteFault(), MiResolveTransitionFault(), MiSectionInitialization(), MiSegmentDelete(), MiSessionCommitImagePages(), MiSessionCreateInternal(), MiSessionUnloadAllImages(), MiSessionWideReserveImageAddress(), MiSetProtectionOnSection(), MiShareSessionImage(), MiSnapThunk(), MiWaitForInPageComplete(), MiWriteComplete(), MmAccessFault(), MmAdjustWorkingSetSize(), MmCallDllInitialize(), MmCheckSystemImage(), MmCopyToCachedPage(), MmCopyVirtualMemory(), MmCreatePeb(), MmCreateSection(), MmDeleteTeb(), MmExtendSection(), MmFlushSection(), MmFlushVirtualMemory(), MmGetCrashDumpInformation(), MmGetFileNameForSection(), MmGetSectionRange(), MmGetSystemRoutineAddress(), MmGetVerifierInformation(), MmInitializeProcessAddressSpace(), MmMapIoSpace(), MmMapUserAddressesToPage(), MmMapViewOfSection(), MmProbeAndLockPages(), MmProbeAndLockProcessPages(), MmRemovePhysicalMemory(), MmSessionCreate(), MmSetBankedSection(), MmSetVerifierInformation(), MmShutdownSystem(), MmUnloadSystemImage(), MmUnmapViewOfSection(), MmZeroPageThread(), MyCmpInitHiveFromFile(), MyRegQueryValue(), NapCreateDataSection(), NativeDosCharLength(), NlsKbdInitializePerSystem(), NotificationThread(), NtAcceptConnectPort(), NtAddAtom(), NtAdjustGroupsToken(), NtAdjustPrivilegesToken(), NtAlertResumeThread(), NtAlertThread(), NtAllocateLocallyUniqueId(), NtAllocateUserPhysicalPages(), NtAllocateUuids(), NtAllocateVirtualMemory(), NtAreMappedFilesTheSame(), NtAssignProcessToJobObject(), NtCancelIoFile(), NtCancelTimer(), NtClearEvent(), NtClose(), NtCloseObjectAuditAlarm(), NtCompleteConnectPort(), NtCreateChannel(), NtCreateDirectoryObject(), NtCreateEvent(), NtCreateEventPair(), NtCreateFile(), NtCreateIoCompletion(), NtCreateJobObject(), NtCreateKey(), NtCreateMutant(), NtCreatePagingFile(), NtCreatePort(), NtCreateProcess(), NtCreateProfile(), NtCreateSection(), NtCreateSemaphore(), NtCreateSuperSection(), NtCreateSymbolicLinkObject(), NtCreateThread(), NtCreateTimer(), NtCreateToken(), NtCreateWaitablePort(), NtDelayExecution(), NtDeleteAtom(), NtDeleteFile(), NtDeleteKey(), NtDeleteObjectAuditAlarm(), NtDeleteValueKey(), NtDuplicateObject(), NtDuplicateToken(), NtEnumerateKey(), NtEnumerateValueKey(), NtExtendSection(), NTFastDOSIO(), NtFilterToken(), NtFindAtom(), NtFlushBuffersFile(), NtFlushInstructionCache(), NtFlushKey(), NtFlushVirtualMemory(), NtFreeUserPhysicalPages(), NtFreeVirtualMemory(), NtfsRecFsControl(), NtGetContextThread(), NtImpersonateAnonymousToken(), NtImpersonateClientOfPort(), NtImpersonateThread(), NtListenChannel(), NtListenPort(), NtLoadKey2(), NtLockFile(), NtLockVirtualMemory(), NtMakeTemporaryObject(), NtMapUserPhysicalPages(), NtMapUserPhysicalPagesScatter(), NtMapViewOfSection(), NtMapViewOfSuperSection(), NtNotifyChangeDirectoryFile(), NtNotifyChangeMultipleKeys(), NtOpenChannel(), NtOpenDirectoryObject(), NtOpenEvent(), NtOpenEventPair(), NtOpenFile(), NtOpenIoCompletion(), NtOpenJobObject(), NtOpenKey(), NtOpenMutant(), NtOpenObjectAuditAlarm(), NtOpenProcess(), NtOpenProcessToken(), NtOpenSection(), NtOpenSemaphore(), NtOpenSuperSection(), NtOpenSymbolicLinkObject(), NtOpenThread(), NtOpenThreadToken(), NtOpenTimer(), NtPrivilegeCheck(), NtPrivilegedServiceAuditAlarm(), NtPrivilegeObjectAuditAlarm(), NtProtectVirtualMemory(), NtPulseEvent(), NtQueryAttributesFile(), NtQueryDefaultLocale(), NtQueryDefaultUILanguage(), NtQueryDirectoryFile(), NtQueryDirectoryObject(), NtQueryEaFile(), NtQueryEvent(), NtQueryFullAttributesFile(), NtQueryInformationAtom(), NtQueryInformationFile(), NtQueryInformationJobObject(), NtQueryInformationPort(), NtQueryInformationProcess(), NtQueryInformationThread(), NtQueryInformationToken(), NtQueryInstallUILanguage(), NtQueryIoCompletion(), NtQueryKey(), NtQueryMultipleValueKey(), NtQueryMutant(), NtQueryObject(), NtQueryOpenSubKeys(), NtQueryQuotaInformationFile(), NtQuerySection(), NtQuerySecurityObject(), NtQuerySemaphore(), NtQuerySymbolicLinkObject(), NtQuerySystemEnvironmentValue(), NtQuerySystemInformation(), NtQueryTimer(), NtQueryValueKey(), NtQueryVirtualMemory(), NtQueryVolumeInformationFile(), NtQueueApcThread(), NtRaiseHardError(), NtReadFile(), NtReadFileScatter(), NtReadVirtualMemory(), NtRegisterThreadTerminatePort(), NtReleaseMutant(), NtReleaseSemaphore(), NtRemoveIoCompletion(), NtReplaceKey(), NtReplyPort(), NtReplyWaitReceivePort(), NtReplyWaitReceivePortEx(), NtReplyWaitReplyPort(), NtReplyWaitSendChannel(), NtRequestPort(), NtRequestWaitReplyPort(), NtResetEvent(), NtRestoreKey(), NtResumeThread(), NtSaveKey(), NtSaveMergedKeys(), NtSecureConnectPort(), NtSendWaitReplyChannel(), NtSetContextChannel(), NtSetContextThread(), NtSetDefaultHardErrorPort(), NtSetDefaultLocale(), NtSetDefaultUILanguage(), NtSetEaFile(), NtSetEvent(), NtSetHighEventPair(), NtSetHighWaitLowEventPair(), NtSetInformationFile(), NtSetInformationJobObject(), NtSetInformationKey(), NtSetInformationObject(), NtSetInformationProcess(), NtSetInformationThread(), NtSetInformationToken(), NtSetIoCompletion(), NtSetLdtEntries(), NtSetLowEventPair(), NtSetLowWaitHighEventPair(), NtSetSecurityObject(), NtSetSystemEnvironmentValue(), NtSetSystemInformation(), NtSetTimer(), NtSetUuidSeed(), NtSetValueKey(), NtSetVolumeInformationFile(), NtSignalAndWaitForSingleObject(), NtStartProfile(), NtStopProfile(), NtSuspendThread(), NtSystemDebugControl(), NtTerminateJobObject(), NtTerminateProcess(), NtTerminateThread(), NtUnloadDriver(), NtUnloadKey(), NtUnlockFile(), NtUnlockVirtualMemory(), NtUnmapViewOfSection(), NtUserBuildHimcList(), NtUserBuildHwndList(), NtUserBuildNameList(), NtUserBuildPropList(), NtUserCloseWindowStation(), NtUserConsoleControl(), NtUserCreateLocalMemHandle(), NtUserCreateWindowStation(), NtUserCtxDisplayIOCtl(), NtUserEnumDisplayDevices(), NtUserEnumDisplaySettings(), NtUserGetGuiResources(), NtUserInitialize(), NtUserInitializeClientPfnArrays(), NtUserInitTask(), NtUserLockWindowStation(), NtUserOpenInputDesktop(), NtUserOpenWindowStation(), NtUserProcessConnect(), NtUserQueryInformationThread(), NtUserRemoteConnect(), NtUserRemoteRedrawRectangle(), NtUserRemoteRedrawScreen(), NtUserRemoteStopScreenUpdates(), NtUserResolveDesktopForWOW(), NtUserSetInformationProcess(), NtUserSetInformationThread(), NtUserSetThreadDesktop(), NtUserSetWindowStationUser(), NtUserSoundSentry(), NtUserSwitchDesktop(), NtUserTestForInteractiveUser(), NtUserUnlockWindowStation(), NtUserUserHandleGrantAccess(), NtVdmControl(), NtW32Call(), NtWaitForMultipleObjects(), NtWaitForSingleObject(), NtWaitHighEventPair(), NtWaitLowEventPair(), NtWriteFile(), NtWriteFileGather(), NtWriteVirtualMemory(), NtYieldExecution(), ObAssignObjectSecurityDescriptor(), ObAssignSecurity(), ObCheckCreateObjectAccess(), ObCheckObjectAccess(), ObCreateObject(), ObCreateObjectType(), ObDupHandleProcedure(), ObEnumerateObjectsByType(), ObGetHandleInformation(), ObGetObjectInformation(), ObGetObjectSecurity(), ObInitSystem(), ObInsertObject(), ObOpenObjectByName(), ObOpenObjectByPointer(), ObpAllocateObject(), ObpCaptureHandleInformation(), ObpCaptureObjectCreateInformation(), ObpCaptureObjectName(), ObpCheckObjectReference(), ObpCheckTraverseAccess(), ObpCreateDosDevicesDirectory(), ObpCreateHandle(), ObpCreateUnnamedHandle(), ObpFreeDosDevicesProtection(), ObpGetDosDevicesProtection(), ObpHashSecurityDescriptor(), ObpIncrementHandleCount(), ObpIncrementUnnamedHandleCount(), ObpInitSecurityDescriptorCache(), ObpLookupObjectName(), ObpParseSymbolicLink(), ObpProcessDosDeviceSymbolicLink(), ObpRemoveObjectRoutine(), ObQueryDeviceMapInformation(), ObQueryNameString(), ObQueryObjectAuditingByHandle(), ObQuerySecurityDescriptorInfo(), ObQueryTypeInfo(), ObReferenceObjectByHandle(), ObReferenceObjectByName(), ObSetDeviceMap(), ObSetSecurityDescriptorInfo(), ObSetSecurityObjectByPointer(), obtest(), ObWaitForSingleObject(), OpenAppropriateToken(), OpenCacheKeyEx(), OpenDesktopCompletion(), OpenDevice(), OpenDeviceReparseIndex(), OpenEffectiveToken(), OpenKeyboardLayoutFile(), ParseDesktop(), ParseWindowStation(), pIoQueryBusDescription(), pIoQueryDeviceDescription(), PnPBiosCopyDeviceParamKey(), PnPBiosCopyIoDecode(), PnPBiosEliminateDupes(), PnPBiosGetBiosInfo(), PnPBiosMapper(), PnPBiosTranslateInfo(), PnPBiosWriteInfo(), PnPCheckFixedIoOverrideDecodes(), PnPGetDevnodeExcludeList(), PrependInputBuffer(), processargs(), ProcessCommandLine(), ProcessCommandListInput(), ProcessCommandNumberInput(), ProcessCopyFromCharInput(), ProcessCopyToCharInput(), ProcessCreateConsoleWindow(), ProcessCtrlEvents(), ProcessDeviceChanges(), ProcessHardErrorRequest(), PropertiesDlgShow(), PropertiesUpdate(), PropRoutine(), ProtectHandle(), PsAssignImpersonationToken(), PsConvertToGuiThread(), PsCreateSystemProcess(), PsCreateSystemThread(), PsEnforceExecutionTimeLimits(), PsExitSpecialApc(), PsImpersonateClient(), PsLocateSystemDll(), PsLockProcess(), PsLookupProcessByProcessId(), PsLookupProcessThreadByCid(), PsLookupThreadByThreadId(), PsOpenTokenOfJobObject(), PsOpenTokenOfProcess(), PsOpenTokenOfThread(), Psp386CreateVdmIoListHead(), Psp386InstallIoHandler(), PspAddProcessToJob(), PspApplyJobLimitsToProcess(), PspAssignPrimaryToken(), PspCaptureTokenFilter(), PspCreateProcess(), PspCreateThread(), PspExitNormalApc(), PspInitializeProcessSecurity(), PspInitializeSystemDll(), PspInitPhase1(), PspLookupKernelUserEntryPoints(), PspMapSystemDll(), PspQueryDescriptorThread(), PspQueryLdtInformation(), PspQueryPooledQuotaLimits(), PspQueryQuotaLimits(), PspQueryWorkingSetWatch(), PspSetLdtInformation(), PspSetLdtSize(), PspSetPrimaryToken(), PspSetProcessIoHandlers(), PspSetQuotaLimits(), PspTerminateProcess(), PsSetCreateThreadNotifyRoutine(), PsSetLoadImageNotifyRoutine(), QueryDeviceInfo(), QueryDeviceNameForPath(), QuerySymbolicLink(), QueuePowerRequest(), RawInputThread(), RawReadWaitRoutine(), ReadChars(), ReadConsoleInternal(), ReadInputBuffer(), ReadLayoutFile(), RealUnicodeToFalseUnicode(), RedrawCommandLine(), ReferenceWindowStation(), RegGetKeyValue(), RegisterForDeviceChangeNotifications(), RegLoadAsciiFileAsUnicode(), RegReadBinaryFile(), RegReadMultiSzFile(), RemoteConnect(), RemoteDisableScreen(), RemoteDoBroadcastSystemMessage(), RemoteDoMessage(), RemoteDoSendWindowMessage(), RemoteLogoff(), RemoteMessageThread(), RemoteShadowCleanup(), RemoteShadowStart(), RemoveConsole(), ReplyMessageToTerminalServer(), ResetAllPrivileges(), RevalidateConsole(), RiInitializeRegistryFromAsciiFile(), RtlAbsoluteToSelfRelativeSD(), RtlAcquireRemoveLockEx(), RtlAcquireResourceExclusive(), RtlAcquireResourceShared(), RtlAddActionToRXact(), RtlAddAtomToAtomTable(), RtlAddRange(), RtlAdjustPrivilege(), RtlAllocateHandle(), RtlAllocateHeap(), RtlAllocateHeapSlowly(), RtlAnsiCharToUnicodeChar(), RtlAnsiStringToUnicodeString(), RtlApplyRXact(), RtlApplyRXactNoFlush(), RtlCallbackLpcClient(), RtlCheckForOrphanedCriticalSections(), RtlCheckRegistryKey(), RtlConvertExclusiveToShared(), RtlConvertSharedToExclusive(), RtlConvertSidToUnicodeString(), RtlConvertUiListToApiList(), RtlCopyRangeList(), RtlCreateAndSetSD(), RtlCreateAtomTable(), RtlCreateEnvironment(), RtlCreateHeap(), RtlCreateLpcServer(), RtlCreateProcessParameters(), RtlCreateQueryDebugBuffer(), RtlCreateRegistryKey(), RtlCreateTimer(), RtlCreateTimerQueue(), RtlCreateUnicodeStringFromAsciiz(), RtlCreateUserProcess(), RtlCreateUserSecurityObject(), RtlCreateUserThread(), RtlDebugCreateHeap(), RtlDebugUsageHeap(), RtlDebugZeroHeap(), RtlDefaultNpAcl(), RtlDeleteAtomFromAtomTable(), RtlDeleteCriticalSection(), RtlDeleteOwnersRanges(), RtlDeleteRange(), RtlDeleteRegistryValue(), RtlDeleteTimer(), RtlDeleteTimerQueueEx(), RtlDeregisterWaitEx(), RtlDestroyAtomTable(), RtlDestroyEnvironment(), RtlDestroyHandleTable(), RtlDestroyProcessParameters(), RtlDestroyQueryDebugBuffer(), RtlDnsHostNameToComputerName(), RtlDoesFileExists_UEx(), RtlEmptyAtomTable(), RtlEnumProcessHeaps(), RtlEqualDomainName(), RtlExpandEnvironmentStrings_U(), RtlExtendHeap(), RtlFindMessage(), RtlFormatCurrentUserKeyPath(), RtlFreeHeap(), RtlFreeHeapSlowly(), RtlFreeUserThreadStack(), RtlGetFirstRange(), RtlGetFullPathName_Ustr(), RtlGetLastRange(), RtlGetNtProductType(), RtlImpersonateSelf(), RtlInitializeCriticalSectionAndSpinCount(), RtlInitializeResource(), RtlInitializeRXact(), RtlInt64ToUnicodeString(), RtlIntegerToUnicodeString(), RtlInvertRangeList(), RtlIsRangeAvailable(), RtlLoadStringOrError(), RtlLocalTimeToSystemTime(), RtlLookupAtomInAtomTable(), RtlMBMessageWParamCharToWCS(), RtlMergeRangeLists(), RtlNewInstanceSecurityObject(), RtlNewSecurityGrantedAccess(), RtlOemStringToCountedUnicodeString(), RtlOemStringToUnicodeString(), RtlOpenCurrentUser(), RtlpAddIntersectingRanges(), RtlpAddRange(), RtlpAllocateHeapUsageEntry(), RtlpAllocateTags(), RtlpAllocDeallocQueryBuffer(), RtlpCallQueryRegistryRoutine(), RtlpChangeQueryDebugBufferTarget(), RtlpCheckRelativeDrive(), RtlpCommitQueryDebugInfo(), RtlpCompareKnownAces(), RtlpCompareKnownObjectAces(), RtlpComputeMergedAcl(), RtlpComputeMergedAcl2(), RtlpConvertAclToAutoInherit(), RtlpConvertToAutoInheritSecurityObject(), RtlpCopyAces(), RtlpCreateCriticalSectionSem(), RtlpCreateServerAcl(), RtlpCreateStack(), RtlpCreateUnCommittedRange(), RtlPcToFileHeader(), RtlpDebugPageHeapAllocateVM(), RtlpDebugPageHeapCommitVM(), RtlpDebugPageHeapCreate(), RtlpDebugPageHeapDecommitVM(), RtlpDebugPageHeapRobustProtectVM(), RtlpDeCommitFreeBlock(), RtlpDeleteFromMergedRange(), RtlpDestroyTags(), RtlpDphShouldAllocateInPageHeap(), RtlpExtendHeap(), RtlpFindAndCommitPages(), RtlpFindWaitThread(), RtlpFireTimers(), RtlpFreeStack(), RtlpGenerateInheritAcl(), RtlpGetDefaultsSubjectContext(), RtlpGetIntegerAtom(), RtlpGetRegistryHandle(), RtlpGetTimeRemaining(), RtlpGetWaitEvent(), RtlPinAtomInAtomTable(), RtlpInheritAcl(), RtlpInheritAcl2(), RtlpInitializeEventCache(), RtlpInitializeHeapSegment(), RtlpInitializeTimerThreadPool(), RtlpInitializeWaitThreadPool(), RtlpInitializeWorkerThreadPool(), RtlpIOWorkerThread(), RtlpIsDuplicateAce(), RtlpLpcServerCallback(), RtlpLpcWorkerThread(), RtlpNewSecurityObject(), RtlpNtEnumerateSubKey(), RtlpNtQueryValueKey(), RtlpOpenImageFile(), RtlpProcessWaitCompletion(), RtlpQueryProcessDebugInformationRemote(), RtlpQueueIOWorkerRequest(), RtlpQueueWorkerRequest(), RtlpRaiseException(), RtlProtectHeap(), RtlpSerializeHeap(), RtlpSetSecurityObject(), RtlpStartIOWorkerThread(), RtlpStartThread(), RtlpStartWorkerThread(), RtlpUnWaitCriticalSection(), RtlpValidateCurrentDirectory(), RtlpValidateHeap(), RtlpValidateHeapHeaders(), RtlpValidOwnerSubjectContext(), RtlpWaitForCriticalSection(), RtlpWaitForEvent(), RtlpWaitThread(), RtlpWorkerThread(), RtlpWorkerThreadInitializeTimers(), RtlpWorkerThreadTimerCallback(), RtlQueryAtomInAtomTable(), RtlQueryAtomsInAtomTable(), RtlQueryEnvironmentVariable_U(), RtlQueryInformationAcl(), RtlQueryProcessBackTraceInformation(), RtlQueryProcessDebugInformation(), RtlQueryProcessHeapInformation(), RtlQueryProcessLockInformation(), RtlQueryProcessModuleInformation(), RtlQueryRegistryValues(), RtlQueryTimeZoneInformation(), RtlQueueWorkItem(), RtlReAllocateHeap(), RtlRegisterWait(), RtlReleaseResource(), RtlRemoteCall(), RtlRunEncodeUnicodeString(), RtlSetActiveTimeBias(), RtlSetCurrentDirectory_U(), RtlSetCurrentEnvironment(), RtlSetEnvironmentVariable(), RtlSetIoCompletionCallback(), RtlSetTimeZoneInformation(), RtlShutdownLpcServer(), RtlSystemTimeToLocalTime(), RtlUnicodeStringToAnsiString(), RtlUnicodeStringToCountedOemString(), RtlUnicodeStringToOemString(), RtlUpcaseUnicodeStringToAnsiString(), RtlUpcaseUnicodeStringToCountedOemString(), RtlUpcaseUnicodeStringToOemString(), RtlUpdateTimer(), RtlUsageHeap(), RtlValidateProcessHeaps(), RtlVerifyVersionInfo(), RtlVolumeDeviceToDosName(), RtlWalkHeap(), RtlWCSMessageWParamCharToMB(), RtlWriteRegistryValue(), RtlZeroHeap(), RXactpCommit(), RXactpOpenTargetKey(), ScrollRegion(), SeAccessCheckByType(), SeAssignPrimaryToken(), SeAssignSecurity(), SeAssignSecurityEx(), SeAssignWorldSecurityDescriptor(), SeAuditProcessCreation(), SeCaptureObjectTypeList(), SeCaptureSecurityQos(), SeCaptureSidAndAttributesArray(), SeCloseObjectAuditAlarm(), SeCopyClientToken(), SeCreateClientSecurity(), SeCreateClientSecurityFromSubjectContext(), SeDeleteObjectAuditAlarm(), SeExchangePrimaryToken(), SeFilterToken(), SeImpersonateClientEx(), SeIsChildToken(), SeIsChildTokenByPointer(), SeMakeAnonymousLogonToken(), SeMakeSystemToken(), SendRequest(), SepAccessCheck(), SepAccessCheckAndAuditAlarm(), SepAdjustGroups(), SepAdjustPrivileges(), SepAdtCopyToLsaSharedMemory(), SepAdtInitializeAuditingOptions(), SepAdtInitializeBounds(), SepAdtInitializeCrashOnFail(), SepAdtInitializePrivilegeAuditing(), SepAdtLogAuditRecord(), SepAuditFailed(), SepClientOpenPipe(), SepCreateClientSecurity(), SepCreateImpersonationTokenDacl(), SepCreateToken(), SepDuplicateToken(), SepFilterToken(), SepInheritAcl(), SepInitializationPhase1(), SepInitSystemDacls(), SepOpenTokenOfThread(), SepProbeAndCaptureQosData(), SepProbeAndCaptureString_U(), SepQueryNameString(), SepQueryTypeString(), SepRmCallLsa(), SepRmCommandServerThread(), SepRmCommandServerThreadInit(), SepRmCreateLogonSessionWrkr(), SepRmDbInitialization(), SepRmDeleteLogonSessionWrkr(), SepServerCreatePipe(), SepServerDisconnectPipe(), SepServerImpersonatePipe(), SepServerListenPipe(), SepServerRevertToSelf(), SepTokenInitialization(), SepTransceivePipe(), SepWritePipe(), SeQueryAuthenticationIdSubjectContext(), SeQueryInformationToken(), SeRmInitPhase1(), ServerHandleConnectionRequest(), ServerThread(), ServiceMessageBox(), SeSubProcessToken(), SetConsoleCP(), SetConsoleDisplayMode(), SetConsoleInputExeNameA(), SetConsoleOutputCP(), SetConsolePalette(), SetConsolePaletteInternal(), SetCurrentCommandLine(), SetEnvironment(), SetFont(), SetInformationProcess(), SetInputBufferSize(), SetRAMFont(), SetRAMFontCodePage(), SetScreenBufferFont(), SetUpConsole(), SetUserObjectSecurity(), SeUnregisterLogonSessionTerminatedRoutine(), ShadowHotkey(), SmbTraceStart(), SmbTraceThreadEntry(), SmbTraceToClient(), SrvActivateDebugger(), SrvAddConsoleAlias(), SrvAllocConsole(), SrvCloseHandle(), SrvConsoleMenuControl(), SrvConsoleNotifyLastClose(), SrvCreateConsoleScreenBuffer(), SrvDeviceEvent(), SrvDuplicateHandle(), SrvExpungeConsoleCommandHistory(), SrvFillConsoleOutput(), SrvFlushConsoleInputBuffer(), SrvFreeConsole(), SrvGenerateConsoleCtrlEvent(), SrvGetConsoleAlias(), SrvGetConsoleAliases(), SrvGetConsoleAliasesLength(), SrvGetConsoleAliasExes(), SrvGetConsoleAliasExesLength(), SrvGetConsoleCommandHistory(), SrvGetConsoleCommandHistoryLength(), SrvGetConsoleCP(), SrvGetConsoleCurrentFont(), SrvGetConsoleCursorInfo(), SrvGetConsoleDisplayMode(), SrvGetConsoleFontInfo(), SrvGetConsoleFontSize(), SrvGetConsoleHardwareState(), SrvGetConsoleInput(), SrvGetConsoleKeyboardLayoutName(), SrvGetConsoleLangId(), SrvGetConsoleMode(), SrvGetConsoleMouseInfo(), SrvGetConsoleNumberOfFonts(), SrvGetConsoleNumberOfInputEvents(), SrvGetConsoleScreenBufferInfo(), SrvGetConsoleTitle(), SrvGetConsoleWindow(), SrvGetHandleInformation(), SrvGetLargestConsoleWindowSize(), SrvInvalidateBitMapRect(), SrvLogon(), SrvOpenConsole(), SrvReadConsole(), SrvReadConsoleOutput(), SrvReadConsoleOutputString(), SrvRegisterConsoleVDM(), SrvScrollConsoleScreenBuffer(), SrvSetConsoleActiveScreenBuffer(), SrvSetConsoleCommandHistoryMode(), SrvSetConsoleCP(), SrvSetConsoleCursor(), SrvSetConsoleCursorInfo(), SrvSetConsoleCursorPosition(), SrvSetConsoleDisplayMode(), SrvSetConsoleFont(), SrvSetConsoleHardwareState(), SrvSetConsoleIcon(), SrvSetConsoleKeyShortcuts(), SrvSetConsoleMenuClose(), SrvSetConsoleMode(), SrvSetConsoleNumberOfCommands(), SrvSetConsolePalette(), SrvSetConsoleScreenBufferSize(), SrvSetConsoleTextAttribute(), SrvSetConsoleTitle(), SrvSetConsoleWindowInfo(), SrvSetHandleInformation(), SrvShowConsoleCursor(), SrvVDMConsoleOperation(), SrvVerifyConsoleIoHandle(), SrvWriteConsole(), SrvWriteConsoleInput(), SrvWriteConsoleOutput(), SrvWriteConsoleOutputString(), SubstituteDeviceName(), SynchronousNtFsControlFile(), TerminalServerRequestThread(), TerminateConsole(), TestAccessCheck(), TestAddAce(), TestAssignSecurity(), TestCaptureSecurityDescriptor(), TestChild(), TestCreateAcl(), TestDefaultObjectMethod(), TestDeleteAce(), TestGetAce(), TestParent(), TestQueryInformationAcl(), TestSeAclRtl(), TestSeSecurityDescriptor(), TestSeSid(), TestSetInformationAcl(), TestTokenAdjustGroups(), TestTokenAdjustPrivileges(), TestTokenCopy(), TestTokenImpersonation(), TestTokenInitialize(), TestTokenOpenPrimary(), ThreadThatExcepts(), ThreadThatExits(), UdbgTest1(), UdbgTest2(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteFcbOpen(), UdfCompletePcb(), UdfCreateUserMdl(), UdfDetermineVolumeBounding(), UdfDismountVolume(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfExceptionFilter(), UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfFsdDispatch(), UdfFspDispatch(), UdfInitializeEnumeration(), UdfInitializePcb(), UdfInvalidateVolumes(), UdfLoadSparingTables(), UdfLockVolume(), UdfLockVolumeInternal(), UdfMountVolume(), UdfNonCachedRead(), UdfOpenExistingFcb(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfOplockRequest(), UdfPerformDevIoCtrl(), UdfPerformVerify(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfPurgeVolume(), UdfQueryAlternateNameInfo(), UdfQueryDirectory(), UdfQueryFsAttributeInfo(), UdfQueryFsVolumeInfo(), UdfQueryNameInfo(), UdfQueueClose(), UdfReadSectors(), UdfRecognizeVolume(), UdfsRecFsControl(), UdfUnlockVolume(), UdfUnlockVolumeInternal(), UdfUpcaseName(), UdfUserFsctl(), UdfVerifyFcbOperation(), UdfVerifyVcb(), UdfVerifyVolume(), UnlockConsole(), UnregisterForDeviceChangeNotifications(), UserAddAtom(), UserBeep(), UserClientConnect(), UserClientDllInitialize(), UserClientShutdown(), UserCommitDesktopMemory(), UserCommitSharedMemory(), UserCreateHeap(), UserDeleteAtom(), UserFindAtom(), UserGetAtomName(), UserInitialize(), UserJobCallout(), UserPowerEventCallout(), UserPowerStateCallout(), UserRtlCreateAtomTable(), UserServerDllInitialization(), UserSetConsoleProcessWindowStation(), UserThreadCallout(), ValidateHdesk(), ValidateHwinsta(), vCleanConvertedTTFs(), VdmCallStringIoHandler(), VdmDispatchInterrupts(), VdmDispatchIoToHandler(), VdmDispatchIRQ13(), VdmDispatchPageFault(), VdmDispatchStringIoToHandler(), VdmFlushPrinterWriteData(), VdmpDelayInterrupt(), VdmpInitialize(), VdmpIsThreadTerminating(), VdmpPrinterDirectIoClose(), VdmpPrinterInitialize(), VdmpQueueIntApcRoutine(), VdmpQueueInterrupt(), VdmpQueueIntNormalRoutine(), VdmPrinterStatus(), VdmPrinterWriteData(), VdmpStartExecution(), VdmQueryDirectoryFile(), VdmTraceEvent(), VectorTest(), VideoPortCallout(), vProcessFontEntry(), vSweepFonts(), W32WinStationBroadcastSystemMessage(), W32WinStationDoConnect(), W32WinStationDoDisconnect(), W32WinStationDoMessage(), W32WinStationDoReconnect(), W32WinStationExitWindows(), W32WinStationNtSecurity(), W32WinStationPassthruDisable(), W32WinStationPassthruEnable(), W32WinStationSendWindowMessage(), W32WinStationShadowCleanup(), W32WinStationShadowSetup(), W32WinStationShadowStart(), W32WinStationShadowStop(), W32WinStationTerminate(), W32WinStationThinwireStats(), WaitForInputIdle(), WaitOnPseudoEvent(), Win32CommandChannelThread(), Win32KDriverUnload(), Win32UserInitialize(), WinHelpW(), WinStationAPIInit(), WowExitTask(), WriteBuffer(), WriteConsoleWaitRoutine(), WWSB_AdjustCursorPosition(), WWSB_DoSrvWriteConsole(), WWSB_DoWriteConsole(), WWSB_WriteChars(), xHalExamineMBR(), xHalGetPartialGeometry(), xHalIoAssignDriveLetters(), xHalIoClearPartitionTable(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), xHalIoWritePartitionTable(), xProtectHandle(), xxxActivateDebugger(), xxxAllowSetForegroundWindow(), xxxClientLoadOLE(), xxxClientRegisterDragDrop(), xxxClientRevokeDragDrop(), xxxCloseDesktop(), xxxConnectService(), xxxConsoleControl(), xxxCreateDesktop(), xxxCreateDesktop2(), xxxCreateDisconnectDesktop(), xxxCreateThreadInfo(), xxxCreateWindowStation(), xxxGetThreadDesktop(), xxxHardErrorControl(), xxxHkCallHook(), xxxInitInput(), xxxInitProcessInfo(), xxxInitTerminal(), xxxMinMaximize(), xxxMsgWaitForMultipleObjects(), xxxOpenDesktop(), xxxPollAndWaitForSingleObject(), xxxQueryInformationThread(), xxxRegisterForDeviceClassNotifications(), xxxRemoteDisconnect(), xxxRemoteReconnect(), xxxRemoteShadowSetup(), xxxRemoteShadowStop(), xxxRemoteStopScreenUpdates(), xxxResolveDesktop(), xxxResolveDesktopForWOW(), xxxRestoreCsrssThreadDesktop(), xxxSendMessageEx(), xxxSetCsrssThreadDesktop(), xxxSetInformationThread(), xxxSetProcessInitState(), xxxSetProcessWindowStation(), xxxSleepTask(), xxxSleepThread(), xxxSwitchDesktop(), xxxUpdatePerUserAccessPackSettings(), xxxUserDuplicateObject(), xxxUserNotifyConsoleApplication(), xxxUserNotifyProcessCreate(), xxxUserPowerEventCalloutWorker(), xxxUserPowerStateCalloutWorker(), xxxUserProcessCallout(), xxxWaitForInputIdle(), ZwDeleteFile(), and zzzInitTask().

typedef VOID | ( | FASTCALL * | PIO_COMPLETE_REQUEST | ) |

| Referenced by _ClientCopyDDEIn2(), _ClientToScreen(), _fptrap(), _GetClientRect(), _GetWindowRect(), _InitializeImmEntryTable(), _LoadCursorsAndIcons(), _QueryUserHandles(), _ResetDblClk(), _ScreenToClient(), _SetRipFlags(), _WOWCleanup(), _WOWModuleUnload(), AbandonTransaction(), AccessTimeOutReset(), AddHmodDependency(), AddImeHotKey(), AdjustPushStateForKL(), ApplyFunctionToObjects(), BestSetLastDDEMLError(), BltColor(), BltMe4Times(), BoundCursor(), CalculateMouseTable(), CancelInputState(), CaretBlinkProc(), CcDeallocateVacbLevel(), CcPinFileData(), CcPrepareMdlWrite(), CcPurgeCacheSection(), CcUnmapAndPurge(), ChangeAcquireResourceType(), ChangeDibColors(), ChangeForegroundKeyboardTable(), ChangeMemberState(), CharHandlerFromConsole(), CharHandlerToConsole(), CheckAppStarting(), CheckPlacementBounds(), CheckValidLayoutName(), CheckWHFBits(), ClassFree(), CleanupDirtyDesktops(), CleanupGDI(), CleanUpInstances(), CleanupResources(), ClearHungFlag(), ClearWakeBit(), ClearWakeMask(), CliGetPreloadKeyboardLayouts(), CliImmInitializeHotKeys(), CliSetDefaultImeHotKeys(), CloseDevice(), CloseProtectedHandle(), ClrFTrueVis(), CommonCreateWindowStation(), ConsolePlaySound(), CProfileAssociationPage::ConstructAssociations(), ConvertImeProWtoA(), ConvertRedirectionDCs(), CopyOutputString(), CreateSpb(), CtxBadAppDelay(), DecCursorLevel(), DecPaintCount(), DecrementFreeDCECount(), DecrementRedirectedCount(), DecTimerCount(), DecVisWindows(), DelayedDestroyCacheDC(), DeleteHrgnClip(), DeleteLinkCount(), DeleteMaybeSpecialRgn(), DeleteRedirectionBitmap(), DereferenceClass(), DestroyBitmap(), DestroyBrush(), DestroyC1Window(), DestroyCacheDCEntries(), DestroyDC(), DestroyEmptyCursorObject(), DestroyFont(), DestroyHandleTableObjects(), DestroyImeModeSaver(), DestroyIMEUI(), DestroyKL(), DestroyProcessesClasses(), DestroyProcessesObjects(), DestroyRegion(), DestroyThreadsHotKeys(), DestroyThreadsMessages(), DestroyThreadsObjects(), DestroyThreadsTimers(), DestroyWindowsHotKeys(), DestroyWindowStation(), DestroyWindowsTimers(), CProfileAssociationPage::DeviceListChanged(), DirectedScheduleTask(), CPropertyPage::DisableApplyButton(), DisconnectConv(), DisownClipboard(), DoClientOutStuff(), DoHTColorAdjust(), DoQueuedSyncPaint(), DrawCaptionIcon(), DrawIconCallBack(), DrawPushButton(), DrawSwitchWndHilite(), DumpAllocatedPool(), DumpDDEMessage(), DumpIt(), ECEnableDisableIME(), ECImmSetCompositionFont(), ECImmSetCompositionWindow(), ECInitInsert(), CPropertyPage::EnableApplyButton(), EnterMediaCrit(), EnterPowerCrit(), EnterWowCritSect(), ErrorExit(), ExAllocatePool(), ExceptionTest(), ExFreePool(), ExLockHandleTableExclusive(), ExLockHandleTableShared(), ExUnlockHandleTableExclusive(), ExUnlockHandleTableShared(), fakeImm_v1(), fakeImm_v2(), fakeImm_wv1(), FixupCallbackPointers(), FixupDlgFaceName(), FKActivationTimer(), FKBounceKeyTimer(), FocusSetIMCContext(), ForceEmptyClipboard(), CBufferAllocator::Free(), FreeAllSpbs(), FreeCachedQueues(), FreeConversationResources(), FreeDdeConv(), FreeDDEData(), FreeDDEHandle(), FreeDdeXact(), FreeDesktop(), FreeHook(), FreeImeHotKeys(), FreeInputContext(), FreeKernelEvent(), FreeListFree(), FreeMessageList(), FreeQEntry(), FreeQueue(), FreeSpb(), FreeThreadsWindowHooks(), FreeTimer(), FreeView(), FreeWindowStation(), FsRecGetDeviceSectors(), FsRecGetDeviceSectorSize(), FsRecReadBlock(), FsRtlCopyRead(), FsRtlCopyWrite(), FsRtlInitializeTunnels(), FsRtlMdlReadDev(), FsRtlPrepareMdlWriteDev(), FsRtlProcessFileLock(), FsRtlpSetSymbolicLink(), FsRtlRegisterUncProvider(), FsRtlWorkerThread(), FtCreateKey(), FtOpenKey(), FujitsuOyayubiControl(), GetActiveKeyboardName(), GetConvContext(), GetDefaultWallpaperName(), GetFlashWindowState(), GetImmFileName(), GetMouseCoord(), GetSoftKeyboardDimension(), GetSystemPathName(), GetTimeouts(), GetWindowNCMetrics(), HalpGetFullGeometry(), HandleMediaChangeEvent(), HardErrorHandler(), HardErrorInsert(), HardErrorRemove(), HMChangeOwnerPheProcess(), HMChangeOwnerThread(), HvFreeCell(), IdleTimerProc(), ImeCheckTopmost(), ImeMarkUsedContext(), ImeOpenClose(), ImeSetFutureOwner(), ImeSetImc(), ImeSetTopmost(), ImeSetTopmostChild(), ImmSendNotification(), ImmUnlockClientImc(), ImmUnlockImeDpi(), IncCursorLevel(), IncPaintCount(), IncrementFreeDCECount(), IncrementRedirectedCount(), IncVisWindows(), InitDst8(), InitExtendedEditKeys(), InitFunctionTables(), InitializeImmEntryTable(), InitKeyboard(), InitLoadResources(), InitMessageTables(), InitMice(), InitSKC1Bitmap(), InitSKC1ButtonPos(), InitWindowMsgTable(), InputApc(), InternalInvalidate3(), InternalOpenColorProfile(), InvalidateDce(), InvalidateGDIWindows(), IoAttachDevice(), IoCancelFileOpen(), IoCreateController(), IoCreateDevice(), IoCreateNotificationEvent(), IoCreateSynchronizationEvent(), IoFreeDumpStack(), IoGetDeviceObjectPointer(), IoInitSystem(), IopCancelAlertedRequest(), IopCheckBackupRestorePrivilege(), IopCloseFile(), IopCompleteRequest(), IopCompleteUnloadOrDelete(), IopCreateRootDirectories(), IopDeleteFile(), IopFilterResourceRequirementsCall(), IopGetDumpStack(), IopGetFileName(), IopGetSetSecurityObject(), IopHardErrorThread(), IopInitializeBootDrivers(), IopInitializePlugPlayServices(), IopInvalidateVolumesForDevice(), IopLoadFileSystemDriver(), IopLoadUnloadDriver(), IopMountVolume(), IopParseDevice(), IopQueryXxxInformation(), IopRaiseInformationalHardError(), IopSendMessageToTrackService(), IopSynchronousCall(), IoRaiseHardError(), IoRaiseInformationalHardError(), IoRegisterFileSystem(), IoSetInformation(), IoShutdownSystem(), IoUnregisterFileSystem(), IovAttachDeviceToDeviceStack(), IovDeleteDevice(), IovDetachDevice(), IoVerifyVolume(), IovInitializeIrp(), IovpCompleteRequest(), IovpThrowBogusSynchronousIrp(), JournalTimer(), keybd_event(), KiInitializeKernel(), LeaveDeviceInfoListCrit(), LeaveMediaCrit(), LeaveMouseCrit(), LeavePowerCrit(), LFontAtoLFontW(), LFontWtoLFontA(), LinkCursor(), LinkTransaction(), LoadAppDlls(), LoadLinkInfo(), LoadPreloadKeyboardLayouts(), LockObjectAssignment(), LW_DriversInit(), LW_LoadProfileInitData(), LW_LoadResources(), LW_LoadSomeStrings(), main(), MapDesktop(), MarkDCEInvalid(), MDIActivateDlgInit(), MDIActivateDlgSize(), MiCheckPageFilePath(), MiDereferenceSegmentThread(), MiFlushDirtyBitsToPfn(), MiFreeNonPagedPool(), MiInsertPageInList(), MiMappedPageWriter(), MiModifiedPageWriter(), MiModifiedPageWriterWorker(), MiProtectVirtualMemory(), MiSetPageModified(), MiSetProtectionOnSection(), MiUnmapLockedPagesInUserSpace(), MKHideMouseCursor(), MKShowMouseCursor(), MmMapUserAddressesToPage(), MmSetAddressRangeModified(), MNFreePopup(), MonCloseEventLog(), MonitorConv(), MonitorLink(), MonitorStringHandle(), mouse_event(), MungeClipData(), NlsClearKeyStateToggle(), NlsKbdInitializePerSystem(), NlsKbdSendIMENotification(), NlsKbdSendIMEProc(), NlsSetKeyStateToggle(), NotepadPrint(), NotificationThread(), NtAlertThread(), NtCancelIoFile(), NtLockVirtualMemory(), NtMapUserPhysicalPages(), NtMapUserPhysicalPagesScatter(), NtUnloadDriver(), NtUserAlterWindowStyle(), NtUserModifyUserStartupInfoFlags(), NtUserNotifyIMEStatus(), NtUserNotifyWinEvent(), NtUserSetDbgTag(), NtUserSetRipFlags(), NtUserSetThreadLayoutHandles(), NtUserSetThreadState(), ObpAcquireDescriptorCacheReadLock(), ObpAcquireDescriptorCacheWriteLock(), ObpIncrementHandleCount(), ObpIncrementUnnamedHandleCount(), ObpReleaseDescriptorCacheLock(), OffsetChildren(), ParkIcon(), PasteScreenPalette(), PatchThreadWindows(), PixieHack(), PlayEventSound(), PnPGetDevnodeExcludeList(), PopState(), PostMove(), PostQuitMessage(), ProcessAsyncDDEMsg(), ProcessDDEMLInitiate(), ProcessDeviceChanges(), ProcessKeyboardInput(), ProcessMouseInput(), PseudoDestroyClassWindows(), PspCreateThread(), PspExitThread(), putc(), QueueMouseEvent(), RawInputThread(), Reader(), ReaderTurnedWriter(), ReceiverDied(), RecolorDeskPattern(), RegisterLPK(), RegisterService(), RegisterSystemThread(), ReleaseEditDS(), RemoveHmodDependency(), RemoveKeyboardLayoutFile(), RemoveRedirectionBitmap(), ReorderKeyboardLayouts(), RequestDeviceChange(), ResetOrg(), ResetSharedDesktops(), ResetSystemColors(), RtlAbortRXact(), RtlApplyRXact(), RtlDestroyHeap(), RtlInitializeHeapManager(), RtlInitLargeAnsiString(), RtlInitLargeUnicodeString(), RtlpValidateCurrentDirectory(), Scale2424(), Scale424(), Scale48(), Scale824(), Scale88(), ScrollChildren(), SeFilterToken(), SeImpersonateClient(), SelectInputContext(), SendMsgCleanup(), SendOpenStatusNotify(), SendRegisterMessageToClass(), SetAccessEnabledFlag(), SetCommonStateFlags(), SetConvContext(), SetConvMode(), SetDbgTag(), SetDebugErrorLevel(), SetDebugHotKeys(), SetDialogPointer(), SetFeKeyboardFlags(), SetForegroundPriority(), SetForegroundPriorityProcess(), SetForegroundThread(), SetGlobalCursorLevel(), SetHandleData(), SetHandleInUse(), SetHungFlag(), SetKeyboardRate(), SetLastDDEMLError(), SetLastErrorEx(), SetMinimize(), SetMinMetrics(), SetRipFlags(), SetSysColor(), CPropertyPage::SettingChanged(), SetTopmost(), SetVDMCursorBounds(), SetVisible(), SetWakeBit(), ShowSKC1Window(), ShutdownConversation(), SKC1ButtonDown(), SKC1DrawBitmap(), SKC1DrawConvexRect(), SKC1DrawDragBorder(), SKC1DrawLabel(), SKC1InvertButton(), SmbTraceStart(), SoundSentryTimer(), SpbCheck(), SpbCheckDce(), SpbCheckPwnd(), SpbCheckRect(), SplFreeResource(), StopFilterKeysTimers(), StubFreeSMS(), SwitchToThisWindow(), SwitchWndCleanup(), TellWOWThehDlg(), TerminateConsole(), TimersProc(), TrackFullscreenMode(), TurnOffMouseKeys(), UdfAddVmcbMapping(), UdfLoadSparingTables(), UdfMultipleAsync(), UdfPerformDevIoCtrl(), UdfPnpCancelRemove(), UdfRemoveVmcbMapping(), UdfSingleAsync(), UdfVerifyVcb(), UdfVmcbLbnToVbn(), UdfVmcbVbnToLbn(), UIntToStr(), UnblockWriteConsole(), UnlinkConvFromOthers(), UnlinkCursor(), UnlinkTransaction(), UnlinkWindow(), UnloadCursorsAndIcons(), UnloadIME(), UnlockAndFreeCPDs(), UnlockConsole(), UnlockNotifyWindow(), UnlockObjectAssignment(), UnmapDesktop(), CProfileAssociationPage::UpdateDeviceListBox(), UpdateJob(), UpdateKeyLights(), UpdateLayeredSprite(), UserAssociateHwnd(), UserDeleteW32Process(), UserDeleteW32Thread(), UserDereferenceObject(), UserEnterUserCritSec(), UserHardError(), UserHardErrorEx(), UserKillTimer(), UserLeaveUserCritSec(), UserRedrawDesktop(), UserRemoveRedirectionBitmap(), UserRtlFreeMem(), UserRtlRaiseStatus(), UserSetDCVisRgn(), UserSetDelayedChangeBroadcastForAllDesktops(), UserSleep(), UT_FreeCBFormat(), vAddLocalType1Font(), vAddRemoteType1Font(), vAddType1Font(), vCheckMMInstance(), vCleanConvertedTTFs(), vFontSweep(), vLoadLocalT1Fonts(), vLoadRemoteT1Fonts(), vLoadT1Fonts(), vMoveFileFromSystemToFontsDir(), vNullTermWideString(), vProcessFontEntry(), vProcessType1FontEntry(), vSweepFonts(), Win32KDriverUnload(), WMCSCallback(), Writer(), xHalExamineMBR(), xHalGetPartialGeometry(), xHalIoClearPartitionTable(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), xHalIoWritePartitionTable(), xxxAccessTimeOutTimer(), xxxAnimateCaption(), xxxBroadcastImeShowStatusChange(), xxxBroadcastPaletteChanged(), xxxButtonEvent(), xxxCancelCoolSwitch(), xxxCancelTracking(), xxxCancelTrackingForThread(), xxxCapture(), xxxChangeMonitorFlags(), xxxCheckImeShowStatusInThread(), xxxContScroll(), xxxCreateClassSmIcon(), xxxDDETrackGetMessageHook(), xxxDDETrackWindowDying(), xxxDesktopThread(), xxxDestroyThreadDDEObject(), xxxDestroyThreadInfo(), xxxDoButtonEvent(), xxxDoSyncPaint(), xxxDoSysExpunge(), xxxDrawCaptionBar(), xxxDrawClipboard(), xxxDrawDragRect(), xxxDWP_DoNCActivate(), xxxFKAcceptanceDelayTimer(), xxxFKRepeatRateTimer(), xxxFlushPalette(), xxxFocusSetInputContext(), xxxFreeImeKeyboardLayouts(), xxxFreeKeyboardLayouts(), xxxFreeListFree(), xxxFreeWindow(), xxxHandleWindowPosChanged(), xxxHardwareMouseKeyUp(), xxxHelpLoop(), xxxHungAppDemon(), xxxImmActivateAndUnloadThreadsLayout(), xxxImmActivateLayout(), xxxImmUnloadLayout(), xxxImmUnloadThreadsLayout(), xxxInternalDoSyncPaint(), xxxInternalInvalidate(), xxxInternalKeyEventDirect(), xxxKeyEvent(), xxxLBoxCaretBlinker(), xxxLW_LoadFonts(), xxxMessageEvent(), xxxMKMoveAccelCursorTimer(), xxxMKMoveConstCursorTimer(), xxxMouseEventDirect(), xxxMoveEvent(), xxxMoveEventAbsolute(), xxxMoveSize(), xxxMS_FlushWigglies(), xxxNextAniIconStep(), xxxNextWindow(), xxxNotifyImeShowStatus(), xxxNotifyIMEStatus(), xxxODI_ColorInit(), xxxOldNextWindow(), xxxPaintIconsInSwitchWindow(), xxxPaintSwitchWindow(), xxxProcessEventMessage(), xxxProcessKeyEvent(), xxxProcessSetWindowPosEvent(), xxxPushKeyEvent(), xxxRealizeDesktop(), xxxReceiveMessage(), xxxRecreateSmallIcons(), xxxRedrawHungWindow(), xxxRedrawHungWindowFrame(), xxxResetDisplayDevice(), xxxSBTrackLoop(), xxxSendChangedMsgs(), xxxSendChildNCPaint(), xxxSendClipboardMessage(), xxxSendNCPaint(), xxxSendOpenStatusNotify(), xxxSetConsoleCaretInfo(), xxxSetPKLinThreads(), xxxSimpleDoSyncPaint(), xxxSimulateShiftF10(), xxxStaticLoadImage(), xxxSwitchToThisWindow(), xxxSystemBroadcastMessage(), xxxSystemTimerProc(), xxxTM_MoveDragRect(), xxxToggleKeysTimer(), xxxTurnOffStickyKeys(), xxxUnlatchStickyKeys(), xxxUpdateModifierState(), xxxUpdateOtherThreadsWindows(), xxxUpdateSystemCursorsFromRegistry(), xxxUpdateSystemIconsFromRegistry(), xxxUpdateThreadsWindows(), xxxUserResetDisplayDevice(), ZapActiveAndFocus(), ZombieCursor(), zzzAnimateCursor(), zzzChangeStates(), zzzInternalSetCursorPos(), zzzRegisterSystemThread(), zzzSetDesktop(), zzzSetFMouseMoved(), and zzzUpdateCursorImage().

## Variable Documentation

ULONG BreakDiskByteOffset

| Definition at line 57 of file iop.h.

ULONG BreakPfn

| Definition at line 58 of file iop.h.

POBJECT_TYPE ExEventObjectType

| Definition at line 561 of file iop.h.

POBJECT_TYPE IoAdapterObjectType

| Definition at line 504 of file iop.h. Referenced by IopCreateObjectTypes().

UNICODE_STRING IoArcBootDeviceName

| Definition at line 529 of file iop.h. Referenced by IoGetDumpStack(), and IopCreateArcNames().

UNICODE_STRING IoArcHalDeviceName

| Definition at line 530 of file iop.h. Referenced by IopCreateArcNames().

POBJECT_TYPE IoCompletionObjectType

| Definition at line 505 of file iop.h.

POBJECT_TYPE IoControllerObjectType

| Definition at line 506 of file iop.h. Referenced by IoCreateController(), and IopCreateObjectTypes().

ULONG IoDeviceHandlerObjectSize

| Definition at line 511 of file iop.h. Referenced by IopCreateObjectTypes().

POBJECT_TYPE IoDeviceHandlerObjectType

| Definition at line 509 of file iop.h. Referenced by IopCreateObjectTypes().

POBJECT_TYPE IoDeviceObjectType

| Definition at line 507 of file iop.h.

POBJECT_TYPE IoDriverObjectType

| Definition at line 508 of file iop.h. Referenced by IoCreateDriver(), IopCreateObjectTypes(), IopGetLegacyVetoListDrivers(), IopInitializeAttributesAndCreateObject(), IopInitializeBuiltinDriver(), IopLoadDriver(), IopReferenceDriverObjectByName(), IoRegisterPlugPlayNotification(), and NtUnloadDriver().

POBJECT_TYPE IoFileObjectType

| Definition at line 510 of file iop.h.

PUCHAR IoLoaderArcBootDeviceName

| Definition at line 531 of file iop.h. Referenced by IopCreateArcNames().

LIST_ENTRY IopBootDriverReinitializeQueueHead

| Definition at line 489 of file iop.h. Referenced by IoInitSystem(), IopInitializeBootDrivers(), and IoRegisterBootDriverReinitialization().

KSPIN_LOCK IopCancelSpinLock

| Definition at line 178 of file iop.h.

LIST_ENTRY IopCdRomFileSystemQueueHead

| Definition at line 486 of file iop.h. Referenced by IoInitSystem(), IopInvalidateVolumesForDevice(), IopMountVolume(), and IoRegisterFileSystem().

KSPIN_LOCK IopCompletionLock

| Definition at line 502 of file iop.h.

NPAGED_LOOKASIDE_LIST IopCompletionLookasideList

| Definition at line 516 of file iop.h. Referenced by IoInitSystem().

GENERIC_MAPPING IopCompletionMapping

| Definition at line 181 of file iop.h. Referenced by IopCreateObjectTypes().

PIOP_HARD_ERROR_PACKET IopCurrentHardError

| Definition at line 153 of file iop.h. Referenced by IoInitSystem(), IopHardErrorThread(), and IoRaiseInformationalHardError().

KSPIN_LOCK IopDatabaseLock

| Definition at line 482 of file iop.h.

ERESOURCE IopDatabaseResource

| Definition at line 483 of file iop.h. Referenced by IoInitSystem(), IopInvalidateVolumesForDevice(), IopMountVolume(), IoRegisterFileSystem(), IoRegisterFsRegistrationChange(), IoShutdownSystem(), IoUnregisterFileSystem(), and IoUnregisterFsRegistrationChange().

LIST_ENTRY IopDiskFileSystemQueueHead

| Definition at line 485 of file iop.h. Referenced by IoInitSystem(), IopInvalidateVolumesForDevice(), IopMountVolume(), IoRegisterFileSystem(), and IoShutdownSystem().

LIST_ENTRY IopDriverReinitializeQueueHead

| Definition at line 490 of file iop.h. Referenced by IoInitSystem(), IopCallDriverAddDeviceQueryRoutine(), IopLoadUnloadDriver(), and IoRegisterDriverReinitialization().

PDUMP_CONTROL_BLOCK IopDumpControlBlock

| Definition at line 532 of file iop.h. Referenced by IoGetCrashDumpInformation(), IopCompleteDumpInitialization(), IopConfigureCrashDump(), IopCreateSummaryDump(), IopFreeDCB(), IopInitializeDCB(), IopWriteToDisk(), and IoWriteCrashDump().

ULONG IopDumpControlBlockChecksum

| Definition at line 533 of file iop.h. Referenced by IopCompleteDumpInitialization(), and IoWriteCrashDump().

ULONG IopErrorLogAllocation

| Definition at line 176 of file iop.h. Referenced by IopAllocateErrorLogEntry(), and IopErrorLogThread().

KSPIN_LOCK IopErrorLogAllocationLock

| Definition at line 177 of file iop.h.

BOOLEAN IopErrorLogDisabledThisBoot

| Definition at line 173 of file iop.h. Referenced by IoInitSystem(), and IoWriteErrorLogEntry().

LIST_ENTRY IopErrorLogListHead

| Definition at line 175 of file iop.h.

KSPIN_LOCK IopErrorLogLock

| Definition at line 174 of file iop.h.

BOOLEAN IopErrorLogPortPending

| Definition at line 172 of file iop.h. Referenced by IopErrorLogGetEntry(), IopErrorLogQueueRequest(), and IoWriteErrorLogEntry().

WORK_QUEUE_ITEM IopErrorLogWorkItem

| Definition at line 171 of file iop.h. Referenced by IopErrorLogDpc(), and IoWriteErrorLogEntry().

GENERIC_MAPPING IopFileMapping

| Definition at line 180 of file iop.h. Referenced by IoGetFileObjectGenericMapping(), and IopCreateObjectTypes().

LIST_ENTRY IopFsNotifyChangeQueueHead

| Definition at line 493 of file iop.h. Referenced by IoInitSystem(), IoRegisterFileSystem(), IoRegisterFsRegistrationChange(), IoUnregisterFileSystem(), and IoUnregisterFsRegistrationChange().

IOP_HARD_ERROR_QUEUE IopHardError

| Definition at line 152 of file iop.h. Referenced by IoInitSystem(), IopHardErrorThread(), IopRaiseInformationalHardError(), and IoRaiseInformationalHardError().

NPAGED_LOOKASIDE_LIST IopLargeIrpLookasideList

| Definition at line 513 of file iop.h. Referenced by IoInitSystem().

ULONG IopLargeIrpStackLocations

| Definition at line 501 of file iop.h.

LINK_TRACKING_PACKET IopLinkTrackingPacket

| Definition at line 540 of file iop.h. Referenced by IoInitSystem(), and IopSendMessageToTrackService().

KEVENT IopLinkTrackingPortObject

| Definition at line 539 of file iop.h. Referenced by IoInitSystem(), and IopSendMessageToTrackService().

PKEVENT IopLinkTrackingServiceEvent

| Definition at line 538 of file iop.h. Referenced by IoInitSystem(), IopConnectLinkTrackingPort(), and IopSendMessageToTrackService().

PVOID IopLinkTrackingServiceObject

| Definition at line 537 of file iop.h. Referenced by IopConnectLinkTrackingPort(), and IopSendMessageToTrackService().

PVOID IopLoaderBlock

| Definition at line 542 of file iop.h. Referenced by IoGetBootDiskInformation(), IoInitSystem(), and IopProcessNewDeviceNode().

ULONG IopLookasideIrpFloat

| Definition at line 546 of file iop.h. Referenced by IopAllocateIrpPrivate(), and IopFreeIrp().

ULONG IopLookasideIrpLimit

| Definition at line 547 of file iop.h. Referenced by IoInitSystem(), IopAllocateIrpPrivate(), and IopFreeIrp().

NPAGED_LOOKASIDE_LIST IopMdlLookasideList

| Definition at line 515 of file iop.h. Referenced by IoInitSystem().

LIST_ENTRY IopNetworkFileSystemQueueHead

| Definition at line 487 of file iop.h. Referenced by IoInitSystem(), and IoRegisterFileSystem().

LIST_ENTRY IopNotifyLastChanceShutdownQueueHead

| Definition at line 492 of file iop.h. Referenced by IoInitSystem(), IoRegisterLastChanceShutdownNotification(), IoShutdownSystem(), and IoUnregisterShutdownNotification().

LIST_ENTRY IopNotifyShutdownQueueHead

| Definition at line 491 of file iop.h. Referenced by IoInitSystem(), IoRegisterShutdownNotification(), IoShutdownSystem(), and IoUnregisterShutdownNotification().

ULONG IopQueryFsOperationAccess[]

| Definition at line 525 of file iop.h. Referenced by IoCheckFunctionAccess(), IoInitSystem(), and NtQueryVolumeInformationFile().

UCHAR IopQueryFsOperationLength[]

| Definition at line 523 of file iop.h. Referenced by IoCheckQuerySetVolumeInformation(), IoInitSystem(), and NtQueryVolumeInformationFile().

ULONG IopQueryOperationAccess[]

| Definition at line 520 of file iop.h. Referenced by IoCheckFunctionAccess(), IoInitSystem(), and NtQueryInformationFile().

UCHAR IopQueryOperationLength[]

| Definition at line 518 of file iop.h. Referenced by IoCheckQuerySetFileInformation(), IoInitSystem(), and NtQueryInformationFile().

UCHAR IopQuerySetAlignmentRequirement[]

| Definition at line 522 of file iop.h. Referenced by BuildQueryDirectoryIrp(), NtQueryInformationFile(), and NtSetInformationFile().

UCHAR IopQuerySetFsAlignmentRequirement[]

| Definition at line 527 of file iop.h. Referenced by NtQueryVolumeInformationFile(), and NtSetVolumeInformationFile().

KSEMAPHORE IopRegistrySemaphore

| Definition at line 495 of file iop.h. Referenced by IoInitSystem(), IopAllocateBootResources(), IopAllocateResources(), IopLegacyResourceAllocation(), IopQueryConflictList(), IopReallocateResources(), and IopRebalance().

BOOLEAN IopRemoteBootCardInitialized

| Definition at line 544 of file iop.h. Referenced by IopSetupRemoteBootCard().

ERESOURCE IopSecurityResource

| Definition at line 484 of file iop.h. Referenced by IoInitSystem(), IopGetSetSecurityObject(), IopParseDevice(), and IopSetDeviceSecurityDescriptors().

ULONG IopSetFsOperationAccess[]

| Definition at line 526 of file iop.h. Referenced by IoCheckFunctionAccess(), IoInitSystem(), and NtSetVolumeInformationFile().

UCHAR IopSetFsOperationLength[]

| Definition at line 524 of file iop.h. Referenced by IoCheckQuerySetVolumeInformation(), IoInitSystem(), and NtSetVolumeInformationFile().

ULONG IopSetOperationAccess[]

| Definition at line 521 of file iop.h. Referenced by IoCheckFunctionAccess(), IoInitSystem(), and NtSetInformationFile().

UCHAR IopSetOperationLength[]

| Definition at line 519 of file iop.h. Referenced by IoCheckQuerySetFileInformation(), IoInitSystem(), and NtSetInformationFile().

NPAGED_LOOKASIDE_LIST IopSmallIrpLookasideList

| Definition at line 514 of file iop.h. Referenced by IoInitSystem().

LIST_ENTRY IopTapeFileSystemQueueHead

| Definition at line 488 of file iop.h. Referenced by IoInitSystem(), IopInvalidateVolumesForDevice(), IopMountVolume(), and IoRegisterFileSystem().

KTIMER IopTimer

| Definition at line 499 of file iop.h. Referenced by IoInitSystem().

ULONG IopTimerCount

| Definition at line 500 of file iop.h. Referenced by IopRemoveTimerFromTimerList(), IopTimerDispatch(), IoStartTimer(), and IoStopTimer().

KDPC IopTimerDpc

| Definition at line 498 of file iop.h. Referenced by IoInitSystem().

KSPIN_LOCK IopTimerLock

| Definition at line 496 of file iop.h.

LIST_ENTRY IopTimerQueueHead

| Definition at line 497 of file iop.h. Referenced by IoInitializeTimer(), IoInitSystem(), and IopTimerDispatch().

LONG IopUniqueDeviceObjectNumber

| Definition at line 535 of file iop.h. Referenced by IoCreateDevice(), and IoInitSystem().

BOOLEAN IopVerifierOn

| Definition at line 548 of file iop.h. Referenced by IoCancelIrp(), IovCallDriver(), IovCompleteRequest(), IoVerifierInit(), IovFreeIrpPrivate(), and IovSpecialIrpCallDriver().

KSPIN_LOCK IopVpbSpinLock

| Definition at line 179 of file iop.h.

KSPIN_LOCK IoStatisticsLock

| Definition at line 494 of file iop.h.

PIO_ALLOCATE_IRP pIoAllocateIrp

| Definition at line 553 of file iop.h. Referenced by IoAllocateIrp(), IopSetIoRoutines(), and IoVerifierInit().

PIO_CALL_DRIVER pIofCallDriver

| Definition at line 550 of file iop.h. Referenced by IofCallDriver(), IopSetIoRoutines(), and IoVerifierInit().

PIO_COMPLETE_REQUEST pIofCompleteRequest

| Definition at line 551 of file iop.h. Referenced by IofCompleteRequest(), IopSetIoRoutines(), and IoVerifierInit().

PIO_FREE_IRP pIoFreeIrp

| Definition at line 552 of file iop.h. Referenced by IoFreeIrp(), IopSetIoRoutines(), and IoVerifierInit().