#include <ntddk.h>
NTSTATUS FASTCALL
MyIoCallDriver(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDRIVER_OBJECT DriverObject;
PIO_STACK_LOCATION Param;
if(!Irp)return STATUS_UNSUCCESSFUL;
if(!DeviceObject) return STATUS_UNSUCCESSFUL;
DriverObject = DeviceObject->DriverObject;
if(!DriverObject) return STATUS_UNSUCCESSFUL;
IoSetNextIrpStackLocation(Irp);
Param = IoGetCurrentIrpStackLocation(Irp);
Param->DeviceObject = DeviceObject;
return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
}
NTSTATUS STDCALL
MypCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN CREATE_FILE_TYPE CreateFileType,
IN PVOID ExtraCreateParameters OPTIONAL,
IN ULONG Options)
{
PFILE_OBJECT FileObject;
NTSTATUS Status;
PIRP Irp;
PIO_STACK_LOCATION StackLoc;
IO_SECURITY_CONTEXT SecurityContext;
KPROCESSOR_MODE PreviousMode;
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
*FileHandle = 0;
PreviousMode = ExGetPreviousMode();
Status = ObCreateObject(PreviousMode,
IoFileObjectType,
ObjectAttributes,
PreviousMode,
NULL,
sizeof(FILE_OBJECT),
0,
0,
(PVOID*)&FileObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
/*
Get Us To The Lowest Device~
*/
PDEVICE_OBJECT DVobj;
DVobj = FileObject->DeviceObject;
while((DVobj->NextDevice)││(DVobj->AttachedDevice))
{
if(DVobj->NextDevice!=DVobj->AttachedDevice)&&(DVobj!=DVobj->NextDevice)&&(DVobj!=DVobj->AttachedDevice))
{
DVobj = (DVobj->NextDevice ? DVobj->NextDevice : DVobj->AttachedDevice);
}else break ;
}
FileObject ->DeviceBject = DVobj;
Status = ObInsertObject ((PVOID)FileObject,
NULL,
DesiredAccess,
0,
NULL,
FileHandle);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (FileObject);
return(Status);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
{
FileObject->Flags │= (FO_ALERTABLE_IO │ FO_SYNCHRONOUS_IO);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
{
FileObject->Flags │= FO_SYNCHRONOUS_IO;
}
if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
FileObject->Flags │= FO_NO_INTERMEDIATE_BUFFERING;
SecurityContext.SecurityQos = NULL; /* ?? */
SecurityContext.AccessState = NULL; /* ?? */
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0; /* ?? */
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
/*
* Create a new IRP to hand to
* the FS driver: this may fail
* due to resource shortage.
*/
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
if (Irp == NULL)
{
ZwClose(FileHandle);
return (STATUS_UNSUCCESSFUL);
}
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->UserEvent = &FileObject->Event;
if (AllocationSize)
{
Irp->Overlay.AllocationSize = *AllocationSize;
}
/*
* Get the stack location for the new
* IRP and prepare it.
*/
StackLoc = IoGetNextIrpStackLocation(Irp);
switch (CreateFileType)
{
default:
case CreateFileTypeNone:
StackLoc->MajorFunction = IRP_MJ_CREATE;
break;
case CreateFileTypeNamedPipe:
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
break;
case CreateFileTypeMailslot:
StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
break;
}
StackLoc->MinorFunction = 0;
StackLoc->Flags = (UCHAR)Options;
StackLoc->Control = 0;
StackLoc->DeviceObject = FileObject->DeviceObject;
StackLoc->FileObject = FileObject;
StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
StackLoc->Parameters.Create.Options │= (CreateDisposition << 24);
StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
StackLoc->Parameters.Create.EaLength = EaLength;
/*
* Now call the driver and
* possibly wait if it can
* not complete the request
* immediately.
*/
Status = MyIoCallDriver(FileObject->DeviceObject, Irp );
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event,
Executive,
PreviousMode,
FALSE,
NULL);
Status = IoStatusBlock->Status;
}
if (!NT_SUCCESS(Status))
{
FileObject->DeviceObject = NULL;
FileObject->Vpb = NULL;
ZwClose(FileHandle);
}
return (Status);
}
NTSTATUS STDCALL
MyCreateFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocateSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength)
{
return MypCreateFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocateSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength,
CreateFileTypeNone,
NULL,
0);
}
NTSTATUS STDCALL
MyOpenFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions)
{
return MypCreateFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
NULL,
0,
ShareAccess,
FILE_OPEN,
OpenOptions,
NULL,
0,
CreateFileTypeNone,
NULL,
0);
}
NTSTATUS STDCALL
MyReadFile (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL;
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_DATA,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (ByteOffset == NULL)
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
{
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
ByteOffset = &FileObject->CurrentByteOffset;
}
if (Event != NULL)
{
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
PreviousMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
return(Status);
}
KeClearEvent(EventObject);
}
KeClearEvent(&FileObject->Event);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
FileObject->DeviceObject,
Buffer,
Length,
ByteOffset,
EventObject,
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->Parameters.Read.Key = Key ? *Key : 0;
Status = MyIoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
Status = KeWaitForSingleObject (&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = IoStatusBlock->Status;
}
return Status;
}
NTSTATUS STDCALL
MyWriteFile (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL;
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (ByteOffset == NULL)
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
{
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
ByteOffset = &FileObject->CurrentByteOffset;
}
if (Event != NULL)
{
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
PreviousMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
return(Status);
}
KeClearEvent(EventObject);
}
KeClearEvent(&FileObject->Event);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
FileObject->DeviceObject,
Buffer,
Length,
ByteOffset,
EventObject,
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->Parameters.Write.Key = Key ? *Key : 0;
Status = MyIoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
Status = KeWaitForSingleObject (&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = IoStatusBlock->Status;
}
return Status;
}
int __cdecl _open(const char*FileName,int oflag, int pmode)
{
HANDLE hFile=0;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING unicodeFullName;
OBJECT_ATTRIBUTES objectAttributes;
ANSI_STRING as;
RtlInitAnsiString(&as, FileName);
RtlAnsiStringToUnicodeString(&unicodeFullName, &as, TRUE);
InitializeObjectAttributes( &objectAttributes,
&unicodeFullName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NTSTATUS ntStatus = MyOpenFile( &hFile,
GENERIC_READ │ GENERIC_WRITE │ SYNCHRONIZE,
&objectAttributes,
&ioStatus,
FILE_SHARE_READ │ FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if(!NT_SUCCESS(ntStatus)) // if error - try to open for reading
{
ntStatus = MyOpenFile( &hFile,
GENERIC_READ │ SYNCHRONIZE,
&objectAttributes,
&ioStatus,
FILE_SHARE_READ │ FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if(!NT_SUCCESS(ntStatus))
{
return 0;
}
}
return (int)hFile;
}
int __cdecl open(const char*FileName,int oflag, int pmode)
{
return _open(FileName,oflag,pmode);
}
int __cdecl _creat(const char*FileName, int pmode)
{
HANDLE hFile=0;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING unicodeFullName;
OBJECT_ATTRIBUTES objectAttributes;
ANSI_STRING as;
RtlInitAnsiString(&as, FileName);
RtlAnsiStringToUnicodeString(&unicodeFullName, &as, TRUE);
InitializeObjectAttributes( &objectAttributes,
&unicodeFullName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NTSTATUS ntStatus = MyCreateFile( &hFile,
GENERIC_READ │ GENERIC_WRITE │ SYNCHRONIZE,
&objectAttributes,
&ioStatus, 0, pmode,
FILE_SHARE_READ │ FILE_SHARE_WRITE,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,0,0);
if(!NT_SUCCESS(ntStatus)) // if error - try to open for reading
{
return 0;
}
return (int)hFile;
}
void __cdecl _close(int hFile)
{
if(hFile)
ZwClose((HANDLE)hFile);
}
void __cdecl close(int hFile)
{
_close(hFile);
}
int __cdecl _read( int handle, void *buffer, unsigned int count )
{
IO_STATUS_BLOCK ioStatus;
NTSTATUS ntStatus;
if(!NT_SUCCESS(ntStatus=MyReadFile((HANDLE)handle,0,0,0,&ioStatus,(void*)buffer,count,0,0)))
{
return 0;
} else
return ioStatus.Information;
}
int __cdecl _write( int handle, const void *buffer, unsigned int count )
{
IO_STATUS_BLOCK ioStatus;
NTSTATUS ntStatus;
if(!NT_SUCCESS(ntStatus=MyWriteFile((HANDLE)handle,0,0,0,&ioStatus,(void*)buffer,count,0,0)))
{
return 0;
} else
return ioStatus.Information;
}
NTSTATUS FASTCALL
MyIoCallDriver(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDRIVER_OBJECT DriverObject;
PIO_STACK_LOCATION Param;
if(!Irp)return STATUS_UNSUCCESSFUL;
if(!DeviceObject) return STATUS_UNSUCCESSFUL;
DriverObject = DeviceObject->DriverObject;
if(!DriverObject) return STATUS_UNSUCCESSFUL;
IoSetNextIrpStackLocation(Irp);
Param = IoGetCurrentIrpStackLocation(Irp);
Param->DeviceObject = DeviceObject;
return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
}
NTSTATUS STDCALL
MypCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength,
IN CREATE_FILE_TYPE CreateFileType,
IN PVOID ExtraCreateParameters OPTIONAL,
IN ULONG Options)
{
PFILE_OBJECT FileObject;
NTSTATUS Status;
PIRP Irp;
PIO_STACK_LOCATION StackLoc;
IO_SECURITY_CONTEXT SecurityContext;
KPROCESSOR_MODE PreviousMode;
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
*FileHandle = 0;
PreviousMode = ExGetPreviousMode();
Status = ObCreateObject(PreviousMode,
IoFileObjectType,
ObjectAttributes,
PreviousMode,
NULL,
sizeof(FILE_OBJECT),
0,
0,
(PVOID*)&FileObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
/*
Get Us To The Lowest Device~
*/
PDEVICE_OBJECT DVobj;
DVobj = FileObject->DeviceObject;
while((DVobj->NextDevice)││(DVobj->AttachedDevice))
{
if(DVobj->NextDevice!=DVobj->AttachedDevice)&&(DVobj!=DVobj->NextDevice)&&(DVobj!=DVobj->AttachedDevice))
{
DVobj = (DVobj->NextDevice ? DVobj->NextDevice : DVobj->AttachedDevice);
}else break ;
}
FileObject ->DeviceBject = DVobj;
Status = ObInsertObject ((PVOID)FileObject,
NULL,
DesiredAccess,
0,
NULL,
FileHandle);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject (FileObject);
return(Status);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)
{
FileObject->Flags │= (FO_ALERTABLE_IO │ FO_SYNCHRONOUS_IO);
}
if (CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)
{
FileObject->Flags │= FO_SYNCHRONOUS_IO;
}
if( CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING )
FileObject->Flags │= FO_NO_INTERMEDIATE_BUFFERING;
SecurityContext.SecurityQos = NULL; /* ?? */
SecurityContext.AccessState = NULL; /* ?? */
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0; /* ?? */
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
/*
* Create a new IRP to hand to
* the FS driver: this may fail
* due to resource shortage.
*/
Irp = IoAllocateIrp(FileObject->DeviceObject->StackSize, FALSE);
if (Irp == NULL)
{
ZwClose(FileHandle);
return (STATUS_UNSUCCESSFUL);
}
//trigger FileObject/Event dereferencing
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->UserEvent = &FileObject->Event;
if (AllocationSize)
{
Irp->Overlay.AllocationSize = *AllocationSize;
}
/*
* Get the stack location for the new
* IRP and prepare it.
*/
StackLoc = IoGetNextIrpStackLocation(Irp);
switch (CreateFileType)
{
default:
case CreateFileTypeNone:
StackLoc->MajorFunction = IRP_MJ_CREATE;
break;
case CreateFileTypeNamedPipe:
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
break;
case CreateFileTypeMailslot:
StackLoc->MajorFunction = IRP_MJ_CREATE_MAILSLOT;
break;
}
StackLoc->MinorFunction = 0;
StackLoc->Flags = (UCHAR)Options;
StackLoc->Control = 0;
StackLoc->DeviceObject = FileObject->DeviceObject;
StackLoc->FileObject = FileObject;
StackLoc->Parameters.Create.SecurityContext = &SecurityContext;
StackLoc->Parameters.Create.Options = (CreateOptions & FILE_VALID_OPTION_FLAGS);
StackLoc->Parameters.Create.Options │= (CreateDisposition << 24);
StackLoc->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
StackLoc->Parameters.Create.EaLength = EaLength;
/*
* Now call the driver and
* possibly wait if it can
* not complete the request
* immediately.
*/
Status = MyIoCallDriver(FileObject->DeviceObject, Irp );
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event,
Executive,
PreviousMode,
FALSE,
NULL);
Status = IoStatusBlock->Status;
}
if (!NT_SUCCESS(Status))
{
FileObject->DeviceObject = NULL;
FileObject->Vpb = NULL;
ZwClose(FileHandle);
}
return (Status);
}
NTSTATUS STDCALL
MyCreateFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocateSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength)
{
return MypCreateFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
AllocateSize,
FileAttributes,
ShareAccess,
CreateDisposition,
CreateOptions,
EaBuffer,
EaLength,
CreateFileTypeNone,
NULL,
0);
}
NTSTATUS STDCALL
MyOpenFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions)
{
return MypCreateFile(FileHandle,
DesiredAccess,
ObjectAttributes,
IoStatusBlock,
NULL,
0,
ShareAccess,
FILE_OPEN,
OpenOptions,
NULL,
0,
CreateFileTypeNone,
NULL,
0);
}
NTSTATUS STDCALL
MyReadFile (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL;
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_READ_DATA,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (ByteOffset == NULL)
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
{
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
ByteOffset = &FileObject->CurrentByteOffset;
}
if (Event != NULL)
{
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
PreviousMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
return(Status);
}
KeClearEvent(EventObject);
}
KeClearEvent(&FileObject->Event);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
FileObject->DeviceObject,
Buffer,
Length,
ByteOffset,
EventObject,
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->Parameters.Read.Key = Key ? *Key : 0;
Status = MyIoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
Status = KeWaitForSingleObject (&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = IoStatusBlock->Status;
}
return Status;
}
NTSTATUS STDCALL
MyWriteFile (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL, /* NOT optional for asynch. operations! */
IN PULONG Key OPTIONAL)
{
NTSTATUS Status;
PFILE_OBJECT FileObject;
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
KPROCESSOR_MODE PreviousMode;
PKEVENT EventObject = NULL;
if (IoStatusBlock == NULL)
return STATUS_ACCESS_VIOLATION;
PreviousMode = ExGetPreviousMode();
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA,
IoFileObjectType,
PreviousMode,
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
if (ByteOffset == NULL)
{
/* a valid ByteOffset is required if asynch. op. */
if (!(FileObject->Flags & FO_SYNCHRONOUS_IO))
{
ObDereferenceObject(FileObject);
return STATUS_INVALID_PARAMETER;
}
ByteOffset = &FileObject->CurrentByteOffset;
}
if (Event != NULL)
{
Status = ObReferenceObjectByHandle(Event,
SYNCHRONIZE,
ExEventObjectType,
PreviousMode,
(PVOID*)&EventObject,
NULL);
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(FileObject);
return(Status);
}
KeClearEvent(EventObject);
}
KeClearEvent(&FileObject->Event);
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
FileObject->DeviceObject,
Buffer,
Length,
ByteOffset,
EventObject,
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->Parameters.Write.Key = Key ? *Key : 0;
Status = MyIoCallDriver(FileObject->DeviceObject, Irp);
if (Status == STATUS_PENDING && (FileObject->Flags & FO_SYNCHRONOUS_IO))
{
Status = KeWaitForSingleObject (&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
if (Status != STATUS_WAIT_0)
{
/* Wait failed. */
return(Status);
}
Status = IoStatusBlock->Status;
}
return Status;
}
int __cdecl _open(const char*FileName,int oflag, int pmode)
{
HANDLE hFile=0;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING unicodeFullName;
OBJECT_ATTRIBUTES objectAttributes;
ANSI_STRING as;
RtlInitAnsiString(&as, FileName);
RtlAnsiStringToUnicodeString(&unicodeFullName, &as, TRUE);
InitializeObjectAttributes( &objectAttributes,
&unicodeFullName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NTSTATUS ntStatus = MyOpenFile( &hFile,
GENERIC_READ │ GENERIC_WRITE │ SYNCHRONIZE,
&objectAttributes,
&ioStatus,
FILE_SHARE_READ │ FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if(!NT_SUCCESS(ntStatus)) // if error - try to open for reading
{
ntStatus = MyOpenFile( &hFile,
GENERIC_READ │ SYNCHRONIZE,
&objectAttributes,
&ioStatus,
FILE_SHARE_READ │ FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
if(!NT_SUCCESS(ntStatus))
{
return 0;
}
}
return (int)hFile;
}
int __cdecl open(const char*FileName,int oflag, int pmode)
{
return _open(FileName,oflag,pmode);
}
int __cdecl _creat(const char*FileName, int pmode)
{
HANDLE hFile=0;
IO_STATUS_BLOCK ioStatus;
UNICODE_STRING unicodeFullName;
OBJECT_ATTRIBUTES objectAttributes;
ANSI_STRING as;
RtlInitAnsiString(&as, FileName);
RtlAnsiStringToUnicodeString(&unicodeFullName, &as, TRUE);
InitializeObjectAttributes( &objectAttributes,
&unicodeFullName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
NTSTATUS ntStatus = MyCreateFile( &hFile,
GENERIC_READ │ GENERIC_WRITE │ SYNCHRONIZE,
&objectAttributes,
&ioStatus, 0, pmode,
FILE_SHARE_READ │ FILE_SHARE_WRITE,
FILE_OVERWRITE_IF,
FILE_SYNCHRONOUS_IO_NONALERT,0,0);
if(!NT_SUCCESS(ntStatus)) // if error - try to open for reading
{
return 0;
}
return (int)hFile;
}
void __cdecl _close(int hFile)
{
if(hFile)
ZwClose((HANDLE)hFile);
}
void __cdecl close(int hFile)
{
_close(hFile);
}
int __cdecl _read( int handle, void *buffer, unsigned int count )
{
IO_STATUS_BLOCK ioStatus;
NTSTATUS ntStatus;
if(!NT_SUCCESS(ntStatus=MyReadFile((HANDLE)handle,0,0,0,&ioStatus,(void*)buffer,count,0,0)))
{
return 0;
} else
return ioStatus.Information;
}
int __cdecl _write( int handle, const void *buffer, unsigned int count )
{
IO_STATUS_BLOCK ioStatus;
NTSTATUS ntStatus;
if(!NT_SUCCESS(ntStatus=MyWriteFile((HANDLE)handle,0,0,0,&ioStatus,(void*)buffer,count,0,0)))
{
return 0;
} else
return ioStatus.Information;
}
本文介绍了一个基于NTFS文件系统的自定义文件操作实现,包括文件创建、打开、读取及写入等功能。通过直接调用内核API实现了对文件的高级控制,并展示了如何使用这些API来完成常见的文件操作。
2825

被折叠的 条评论
为什么被折叠?



