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_TYPEPTRANSFER_TYPE
typedef _ERROR_LOG_ENTRY ERROR_LOG_ENTRY
typedef _ERROR_LOG_ENTRYPERROR_LOG_ENTRY
typedef _IOP_HARD_ERROR_QUEUE IOP_HARD_ERROR_QUEUE
typedef _IOP_HARD_ERROR_QUEUEPIOP_HARD_ERROR_QUEUE
typedef _IOP_HARD_ERROR_PACKET IOP_HARD_ERROR_PACKET
typedef _IOP_HARD_ERROR_PACKETPIOP_HARD_ERROR_PACKET
typedef _IOP_APC_HARD_ERROR_PACKET IOP_APC_HARD_ERROR_PACKET
typedef _IOP_APC_HARD_ERROR_PACKETPIOP_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_OBJECTPDUMMY_FILE_OBJECT
typedef _OPEN_PACKET OPEN_PACKET
typedef _OPEN_PACKETPOPEN_PACKET
typedef _LOAD_PACKET LOAD_PACKET
typedef _LOAD_PACKETPLOAD_PACKET
typedef _LINK_TRACKING_PACKET LINK_TRACKING_PACKET
typedef _LINK_TRACKING_PACKETPLINK_TRACKING_PACKET
typedef _REINIT_PACKET REINIT_PACKET
typedef _REINIT_PACKETPREINIT_PACKET
typedef _SHUTDOWN_PACKET SHUTDOWN_PACKET
typedef _SHUTDOWN_PACKETPSHUTDOWN_PACKET
typedef _NOTIFICATION_PACKET NOTIFICATION_PACKET
typedef _NOTIFICATION_PACKETPNOTIFICATION_PACKET
typedef enum _COMPLETION_PACKET_TYPE COMPLETION_PACKET_TYPE
typedef enum _COMPLETION_PACKET_TYPEPCOMPLETION_PACKET_TYPE
typedef _IOP_MINI_COMPLETION_PACKET IOP_MINI_COMPLETION_PACKET
typedef _IOP_MINI_COMPLETION_PACKETPIOP_MINI_COMPLETION_PACKET
typedef _MINIPORT_NODE MINIPORT_NODE
typedef _MINIPORT_NODEPMINIPORT_NODE
typedef _DUMP_CONTROL_BLOCK DUMP_CONTROL_BLOCK
typedef _DUMP_CONTROL_BLOCKPDUMP_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.

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().


Generated on Sat May 15 19:44:20 2004 for test by doxygen 1.3.7