Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840/* * COPYRIGHT: See COPYRIGHT.TXT * PROJECT: Ext2 File System Driver for WinNT/2K/XP * FILE: devctl.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://www.ext2fsd.com * UPDATE HISTORY: */
/* INCLUDES *****************************************************************/
#include "ext2fs.h"
/* GLOBALS ***************************************************************/
extern PEXT2_GLOBAL Ext2Global;
/* DEFINITIONS *************************************************************/
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifExt2DeviceControlCompletion ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context);
#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, Ext2DeviceControl)#pragma alloc_text(PAGE, Ext2DeviceControlNormal)#pragma alloc_text(PAGE, Ext2ProcessVolumeProperty)#pragma alloc_text(PAGE, Ext2ProcessUserProperty)#pragma alloc_text(PAGE, Ext2ProcessGlobalProperty)#pragma alloc_text(PAGE, Ex2ProcessUserPerfStat)#pragma alloc_text(PAGE, Ex2ProcessMountPoint)#if EXT2_UNLOAD#pragma alloc_text(PAGE, Ext2PrepareToUnload)#endif#endif
#ifdef __REACTOS__NTSTATUS NTAPI#elseNTSTATUS#endifExt2DeviceControlCompletion ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context){ if (Irp->PendingReturned) { IoMarkIrpPending(Irp); }
return STATUS_SUCCESS;}
NTSTATUSExt2DeviceControlNormal (IN PEXT2_IRP_CONTEXT IrpContext){ PDEVICE_OBJECT DeviceObject; BOOLEAN CompleteRequest = TRUE; NTSTATUS Status = STATUS_UNSUCCESSFUL;
PEXT2_VCB Vcb;
PIRP Irp; PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION NextIrpSp;
PDEVICE_OBJECT TargetDeviceObject;
_SEH2_TRY {
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
CompleteRequest = TRUE;
DeviceObject = IrpContext->DeviceObject;
if (IsExt2FsDevice(DeviceObject)) { Status = STATUS_INVALID_DEVICE_REQUEST; _SEH2_LEAVE; }
Irp = IrpContext->Irp; IrpSp = IoGetCurrentIrpStackLocation(Irp);
Vcb = (PEXT2_VCB) IrpSp->FileObject->FsContext;
if (!((Vcb) && (Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB)))) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
TargetDeviceObject = Vcb->TargetDeviceObject;
// // Pass on the IOCTL to the driver below //
CompleteRequest = FALSE;
NextIrpSp = IoGetNextIrpStackLocation( Irp ); *NextIrpSp = *IrpSp;
IoSetCompletionRoutine( Irp, Ext2DeviceControlCompletion, NULL, FALSE, TRUE, TRUE );
Status = IoCallDriver(TargetDeviceObject, Irp);
} _SEH2_FINALLY {
if (!IrpContext->ExceptionInProgress) { if (IrpContext) { if (!CompleteRequest) { IrpContext->Irp = NULL; }
Ext2CompleteIrpContext(IrpContext, Status); } } } _SEH2_END;
return Status;}
#if EXT2_UNLOAD
NTSTATUSExt2PrepareToUnload (IN PEXT2_IRP_CONTEXT IrpContext){ PDEVICE_OBJECT DeviceObject; NTSTATUS Status = STATUS_UNSUCCESSFUL; BOOLEAN GlobalDataResourceAcquired = FALSE;
_SEH2_TRY {
ASSERT(IrpContext != NULL);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject;
if (IsExt2FsDevice(DeviceObject)) { Status = STATUS_INVALID_DEVICE_REQUEST; _SEH2_LEAVE; }
ExAcquireResourceExclusiveLite( &Ext2Global->Resource, TRUE );
GlobalDataResourceAcquired = TRUE;
if (FlagOn(Ext2Global->Flags, EXT2_UNLOAD_PENDING)) { DEBUG(DL_ERR, ( "Ext2PrepareUnload: Already ready to unload.\n"));
Status = STATUS_ACCESS_DENIED;
_SEH2_LEAVE; }
{ PEXT2_VCB Vcb; PLIST_ENTRY ListEntry;
ListEntry = Ext2Global->VcbList.Flink;
while (ListEntry != &(Ext2Global->VcbList)) {
Vcb = CONTAINING_RECORD(ListEntry, EXT2_VCB, Next); ListEntry = ListEntry->Flink;
if (Vcb && (!Vcb->ReferenceCount) && IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) { Ext2RemoveVcb(Vcb); Ext2ClearVpbFlag(Vcb->Vpb, VPB_MOUNTED);
Ext2DestroyVcb(Vcb); } } }
if (!IsListEmpty(&(Ext2Global->VcbList))) {
DEBUG(DL_ERR, ( "Ext2PrepareUnload: Mounted volumes exists.\n"));
Status = STATUS_ACCESS_DENIED;
_SEH2_LEAVE; }
IoUnregisterFileSystem(Ext2Global->DiskdevObject); IoUnregisterFileSystem(Ext2Global->CdromdevObject); Ext2Global->DriverObject->DriverUnload = DriverUnload; SetLongFlag(Ext2Global->Flags ,EXT2_UNLOAD_PENDING); Status = STATUS_SUCCESS;
DEBUG(DL_INF, ( "Ext2PrepareToUnload: Driver is ready to unload.\n"));
} _SEH2_FINALLY {
if (GlobalDataResourceAcquired) { ExReleaseResourceLite(&Ext2Global->Resource); }
if (!IrpContext->ExceptionInProgress) { Ext2CompleteIrpContext(IrpContext, Status); } } _SEH2_END;
return Status;}
#endif
extern CHAR gVersion[];extern CHAR gTime[];extern CHAR gDate[];
NTSTATUSExt2ProcessGlobalProperty( IN PDEVICE_OBJECT DeviceObject, IN PEXT2_VOLUME_PROPERTY3 Property3, IN ULONG Length){ PEXT2_VOLUME_PROPERTY3 Property2 = (PVOID)Property3; PEXT2_VOLUME_PROPERTY Property = (PVOID)Property3; struct nls_table * PageTable = NULL;
NTSTATUS Status = STATUS_SUCCESS; BOOLEAN GlobalDataResourceAcquired = FALSE;
_SEH2_TRY {
if (Length < 8 || !IsFlagOn(Property->Flags, EXT2_FLAG_VP_SET_GLOBAL)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
/* query Ext2Fsd's version and built date/time*/ if (Property->Command == APP_CMD_QUERY_VERSION) { PEXT2_VOLUME_PROPERTY_VERSION PVPV = (PEXT2_VOLUME_PROPERTY_VERSION) Property;
if (Length < sizeof(EXT2_VOLUME_PROPERTY_VERSION)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
RtlZeroMemory(&PVPV->Date[0], 0x20); RtlZeroMemory(&PVPV->Time[0], 0x20); RtlZeroMemory(&PVPV->Version[0],0x1C); strncpy(&PVPV->Version[0], gVersion, 0x1B); strncpy(&PVPV->Date[0], gDate, 0x1F); strncpy(&PVPV->Time[0], gTime, 0x1F); _SEH2_LEAVE; }
/* must be property query/set commands */ if (Property->Command == APP_CMD_SET_PROPERTY) { if (Length < sizeof(EXT2_VOLUME_PROPERTY)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } } else if (Property->Command == APP_CMD_SET_PROPERTY2) { if (Length < sizeof(EXT2_VOLUME_PROPERTY2)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } } else if (Property->Command == APP_CMD_SET_PROPERTY3) { if (Length < sizeof(EXT2_VOLUME_PROPERTY3)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } } else { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
ExAcquireResourceExclusiveLite(&Ext2Global->Resource, TRUE); GlobalDataResourceAcquired = TRUE;
switch (Property->Command) {
case APP_CMD_SET_PROPERTY3:
if (Property3->Flags2 & EXT2_VPROP3_AUTOMOUNT) { if (Property3->AutoMount) SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); else ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); }
case APP_CMD_SET_PROPERTY2:
RtlZeroMemory(Ext2Global->sHidingPrefix, HIDINGPAT_LEN); if ((Ext2Global->bHidingPrefix = Property2->bHidingPrefix)) { RtlCopyMemory( Ext2Global->sHidingPrefix, Property2->sHidingPrefix, HIDINGPAT_LEN - 1); } RtlZeroMemory(Ext2Global->sHidingSuffix, HIDINGPAT_LEN); if ((Ext2Global->bHidingSuffix = Property2->bHidingSuffix)) { RtlCopyMemory( Ext2Global->sHidingSuffix, Property2->sHidingSuffix, HIDINGPAT_LEN - 1); }
case APP_CMD_SET_PROPERTY:
if (Property->bReadonly) { ClearLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } else { SetLongFlag(Ext2Global->Flags, EXT2_SUPPORT_WRITING); if (Property->bExt3Writable) { SetLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } else { ClearLongFlag(Ext2Global->Flags, EXT3_FORCE_WRITING); } }
PageTable = load_nls(Property->Codepage); if (PageTable) { memcpy(Ext2Global->Codepage.AnsiName, Property->Codepage, CODEPAGE_MAXLEN); Ext2Global->Codepage.PageTable = PageTable; }
break;
default: break; }
} _SEH2_FINALLY {
if (GlobalDataResourceAcquired) { ExReleaseResourceLite(&Ext2Global->Resource); } } _SEH2_END;
return Status;}
NTSTATUSExt2ProcessVolumeProperty( IN PEXT2_VCB Vcb, IN PEXT2_VOLUME_PROPERTY3 Property3, IN ULONG Length){ struct nls_table * PageTable = NULL; PEXT2_VOLUME_PROPERTY2 Property2 = (PVOID)Property3; PEXT2_VOLUME_PROPERTY Property = (PVOID)Property3; NTSTATUS Status = STATUS_SUCCESS; BOOLEAN VcbResourceAcquired = FALSE;
_SEH2_TRY {
ExAcquireResourceExclusiveLite(&Vcb->MainResource, TRUE); VcbResourceAcquired = TRUE;
if (Property->Command == APP_CMD_SET_PROPERTY || Property->Command == APP_CMD_QUERY_PROPERTY) { if (Length < sizeof(EXT2_VOLUME_PROPERTY)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } } else if (Property->Command == APP_CMD_SET_PROPERTY2 || Property->Command == APP_CMD_QUERY_PROPERTY2) { if (Length < sizeof(EXT2_VOLUME_PROPERTY2)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } } else if (Property->Command == APP_CMD_SET_PROPERTY3 || Property->Command == APP_CMD_QUERY_PROPERTY3) { if (Length < sizeof(EXT2_VOLUME_PROPERTY3)) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } }
switch (Property->Command) {
case APP_CMD_SET_PROPERTY3:
if (Property3->Flags2 & EXT2_VPROP3_AUTOMOUNT) { if (Property3->AutoMount) SetLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); else ClearLongFlag(Ext2Global->Flags, EXT2_AUTO_MOUNT); } if (Property3->Flags2 & EXT2_VPROP3_USERIDS) { SetFlag(Vcb->Flags, VCB_USER_IDS); Vcb->uid = Property3->uid; Vcb->gid = Property3->gid; if (Property3->EIDS) { Vcb->euid = Property3->euid; Vcb->egid = Property3->egid; SetFlag(Vcb->Flags, VCB_USER_EIDS); } else { Vcb->euid = Vcb->egid = 0; ClearFlag(Vcb->Flags, VCB_USER_EIDS); } } else { ClearFlag(Vcb->Flags, VCB_USER_IDS); ClearFlag(Vcb->Flags, VCB_USER_EIDS); Vcb->uid = Vcb->gid = 0; Vcb->euid = Vcb->egid = 0; }
case APP_CMD_SET_PROPERTY2:
RtlZeroMemory(Vcb->sHidingPrefix, HIDINGPAT_LEN);#ifdef __REACTOS__ if (Vcb->bHidingPrefix == Property2->bHidingPrefix) {#else if (Vcb->bHidingPrefix = Property2->bHidingPrefix) {#endif RtlCopyMemory( Vcb->sHidingPrefix, Property2->sHidingPrefix, HIDINGPAT_LEN - 1); }
RtlZeroMemory(Vcb->sHidingSuffix, HIDINGPAT_LEN);#ifdef __REACTOS__ if (Vcb->bHidingSuffix == Property2->bHidingSuffix) {#else if (Vcb->bHidingSuffix = Property2->bHidingSuffix) {#endif RtlCopyMemory( Vcb->sHidingSuffix, Property2->sHidingSuffix, HIDINGPAT_LEN - 1); } Vcb->DrvLetter = Property2->DrvLetter;
case APP_CMD_SET_PROPERTY:
if (Property->bReadonly) { if (IsFlagOn(Vcb->Flags, VCB_INITIALIZED)) { Ext2FlushFiles(NULL, Vcb, FALSE); Ext2FlushVolume(NULL, Vcb, FALSE); } SetLongFlag(Vcb->Flags, VCB_READ_ONLY);
} else {
if (Property->bExt3Writable) { SetLongFlag(Vcb->Flags, VCB_FORCE_WRITING); }
if (!Vcb->IsExt3fs) { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); } else if (!Property->bExt3Writable) { SetLongFlag(Vcb->Flags, VCB_READ_ONLY); } else if (IsFlagOn(Vcb->Flags, VCB_JOURNAL_RECOVER)) { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); Ext2RecoverJournal(NULL, Vcb); if (IsFlagOn(Vcb->Flags, VCB_JOURNAL_RECOVER)) { SetLongFlag(Vcb->Flags, VCB_READ_ONLY); } else { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); } } else { ClearLongFlag(Vcb->Flags, VCB_READ_ONLY); } }
PageTable = load_nls(Property->Codepage); memcpy(Vcb->Codepage.AnsiName, Property->Codepage, CODEPAGE_MAXLEN); Vcb->Codepage.PageTable = PageTable; if (Vcb->Codepage.PageTable) { Ext2InitializeLabel(Vcb, Vcb->SuperBlock); }
break;
case APP_CMD_QUERY_PROPERTY3:
if (IsFlagOn(Ext2Global->Flags, EXT2_AUTO_MOUNT)) { SetFlag(Property3->Flags2, EXT2_VPROP3_AUTOMOUNT); Property3->AutoMount = TRUE; } else { ClearFlag(Property3->Flags2, EXT2_VPROP3_AUTOMOUNT); Property3->AutoMount = FALSE; }
if (IsFlagOn(Vcb->Flags, VCB_USER_IDS)) { SetFlag(Property3->Flags2, EXT2_VPROP3_USERIDS); Property3->uid = Vcb->uid; Property3->gid = Vcb->gid; if (IsFlagOn(Vcb->Flags, VCB_USER_EIDS)) { Property3->EIDS = TRUE; Property3->euid = Vcb->euid; Property3->egid = Vcb->egid; } else { Property3->EIDS = FALSE; } } else { ClearFlag(Property3->Flags2, EXT2_VPROP3_USERIDS); }
case APP_CMD_QUERY_PROPERTY2:
RtlCopyMemory(Property2->UUID, Vcb->SuperBlock->s_uuid, 16); Property2->DrvLetter = Vcb->DrvLetter;
#ifdef __REACTOS__ if (Property2->bHidingPrefix == Vcb->bHidingPrefix) {#else if (Property2->bHidingPrefix = Vcb->bHidingPrefix) {#endif RtlCopyMemory( Property2->sHidingPrefix, Vcb->sHidingPrefix, HIDINGPAT_LEN); } else { RtlZeroMemory( Property2->sHidingPrefix, HIDINGPAT_LEN); }
#ifdef __REACTOS__ if (Property2->bHidingSuffix == Vcb->bHidingSuffix) {#else if (Property2->bHidingSuffix = Vcb->bHidingSuffix) {#endif RtlCopyMemory( Property2->sHidingSuffix, Vcb->sHidingSuffix, HIDINGPAT_LEN); } else { RtlZeroMemory( Property2->sHidingSuffix, HIDINGPAT_LEN); }
case APP_CMD_QUERY_PROPERTY:
Property->bExt2 = TRUE; Property->bExt3 = Vcb->IsExt3fs; Property->bReadonly = IsFlagOn(Vcb->Flags, VCB_READ_ONLY); if (!Property->bReadonly && Vcb->IsExt3fs) { Property->bExt3Writable = TRUE; } else { Property->bExt3Writable = FALSE; }
RtlZeroMemory(Property->Codepage, CODEPAGE_MAXLEN); if (Vcb->Codepage.PageTable) { strncpy(Property->Codepage, Vcb->Codepage.PageTable->charset, CODEPAGE_MAXLEN); } else { strncpy(Property->Codepage, "default", CODEPAGE_MAXLEN); } break;
default: Status = STATUS_INVALID_PARAMETER; break; }
} _SEH2_FINALLY {
if (VcbResourceAcquired) { ExReleaseResourceLite(&Vcb->MainResource); } } _SEH2_END;
return Status;}
NTSTATUSExt2ProcessUserProperty( IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VOLUME_PROPERTY3 Property, IN ULONG Length){ NTSTATUS Status = STATUS_SUCCESS; PEXT2_VCB Vcb = NULL; PDEVICE_OBJECT DeviceObject = NULL;
_SEH2_TRY {
ASSERT(IrpContext != NULL); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
if (Property->Magic != EXT2_VOLUME_PROPERTY_MAGIC) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
DeviceObject = IrpContext->DeviceObject; if (IsExt2FsDevice(DeviceObject)) { Status = Ext2ProcessGlobalProperty(DeviceObject, Property, Length); } else { Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension; if (!((Vcb) && (Vcb->Identifier.Type == EXT2VCB) && (Vcb->Identifier.Size == sizeof(EXT2_VCB)))) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; } Status = Ext2ProcessVolumeProperty(Vcb, Property, Length); }
if (NT_SUCCESS(Status)) { IrpContext->Irp->IoStatus.Information = Length; }
} _SEH2_FINALLY {
if (!IrpContext->ExceptionInProgress) { Ext2CompleteIrpContext(IrpContext, Status); } } _SEH2_END;
return Status;}
NTSTATUSEx2ProcessUserPerfStat( IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_QUERY_PERFSTAT QueryPerf, IN ULONG Length){
#ifndef __REACTOS__ PEXT2_VCB Vcb = NULL;#endif PDEVICE_OBJECT DeviceObject = NULL;
BOOLEAN GlobalDataResourceAcquired = FALSE; NTSTATUS Status = STATUS_SUCCESS;
_SEH2_TRY {
ASSERT(IrpContext != NULL); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject; if (IsExt2FsDevice(DeviceObject)) {
if (QueryPerf->Magic != EXT2_QUERY_PERFSTAT_MAGIC) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
if (QueryPerf->Command != IOCTL_APP_QUERY_PERFSTAT) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
if (Length != EXT2_QUERY_PERFSTAT_SZV1 && Length != EXT2_QUERY_PERFSTAT_SZV2) { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
ExAcquireResourceSharedLite(&Ext2Global->Resource, TRUE); GlobalDataResourceAcquired = TRUE;
if (Length == EXT2_QUERY_PERFSTAT_SZV2) { QueryPerf->Flags = EXT2_QUERY_PERFSTAT_VER2; QueryPerf->PerfStatV2 = Ext2Global->PerfStat; } else { memcpy(&QueryPerf->PerfStatV1.Irps[0], &Ext2Global->PerfStat.Irps[0], FIELD_OFFSET(EXT2_PERF_STATISTICS_V1, Unit)); memcpy(&QueryPerf->PerfStatV1.Unit, &Ext2Global->PerfStat.Unit, sizeof(EXT2_STAT_ARRAY_V1)); memcpy(&QueryPerf->PerfStatV1.Current, &Ext2Global->PerfStat.Current, sizeof(EXT2_STAT_ARRAY_V1)); memcpy(&QueryPerf->PerfStatV1.Size, &Ext2Global->PerfStat.Size, sizeof(EXT2_STAT_ARRAY_V1)); memcpy(&QueryPerf->PerfStatV1.Total, &Ext2Global->PerfStat.Total, sizeof(EXT2_STAT_ARRAY_V1)); }
} else { Status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
if (NT_SUCCESS(Status)) { IrpContext->Irp->IoStatus.Information = Length; }
} _SEH2_FINALLY {
if (GlobalDataResourceAcquired) { ExReleaseResourceLite(&Ext2Global->Resource); }
if (!IrpContext->ExceptionInProgress) { Ext2CompleteIrpContext(IrpContext, Status); } } _SEH2_END
return Status;}
NTSTATUSEx2ProcessMountPoint( IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_MOUNT_POINT MountPoint, IN ULONG Length){ UNICODE_STRING Link; UNICODE_STRING Target; WCHAR Buffer[] = L"\\DosDevices\\Global\\Z:"; NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
_SEH2_TRY {
ASSERT(IrpContext != NULL); ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
DeviceObject = IrpContext->DeviceObject; if (!IsExt2FsDevice(DeviceObject)) { status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
if (Length != sizeof(EXT2_MOUNT_POINT) || MountPoint->Magic != EXT2_APP_MOUNTPOINT_MAGIC) { status = STATUS_INVALID_PARAMETER; _SEH2_LEAVE; }
RtlInitUnicodeString(&Link, Buffer); Buffer[12] = MountPoint->Link[0];
switch (MountPoint->Command) {
case APP_CMD_ADD_DOS_SYMLINK: RtlInitUnicodeString(&Target, &MountPoint->Name[0]); status = IoCreateSymbolicLink(&Link, &Target); break;
case APP_CMD_DEL_DOS_SYMLINK: status = IoDeleteSymbolicLink(&Link); break;
default: status = STATUS_INVALID_PARAMETER; }
} _SEH2_FINALLY {
if (!IrpContext->ExceptionInProgress) { Ext2CompleteIrpContext(IrpContext, status); } } _SEH2_END;
return status;}
NTSTATUSExt2DeviceControl (IN PEXT2_IRP_CONTEXT IrpContext){ PIRP Irp; PIO_STACK_LOCATION irpSp; ULONG code; ULONG length; NTSTATUS Status;
ASSERT(IrpContext);
ASSERT((IrpContext->Identifier.Type == EXT2ICX) && (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
Irp = IrpContext->Irp;
irpSp = IoGetCurrentIrpStackLocation(Irp);
code = irpSp->Parameters.DeviceIoControl.IoControlCode; length = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
switch (code) {
case IOCTL_APP_VOLUME_PROPERTY: Status = Ext2ProcessUserProperty( IrpContext, Irp->AssociatedIrp.SystemBuffer, length ); break;
case IOCTL_APP_QUERY_PERFSTAT: Status = Ex2ProcessUserPerfStat( IrpContext, Irp->AssociatedIrp.SystemBuffer, length ); break;
case IOCTL_APP_MOUNT_POINT: Status = Ex2ProcessMountPoint( IrpContext, Irp->AssociatedIrp.SystemBuffer, length ); break;
#if EXT2_UNLOAD case IOCTL_PREPARE_TO_UNLOAD: Status = Ext2PrepareToUnload(IrpContext); break;#endif default: Status = Ext2DeviceControlNormal(IrpContext); }
return Status;}