Exemple #1
0
BOOLEAN
Ext2FastIoWrite (
    IN PFILE_OBJECT         FileObject,
    IN PLARGE_INTEGER       FileOffset,
    IN ULONG                Length,
    IN BOOLEAN              Wait,
    IN ULONG                LockKey,
    OUT PVOID               Buffer,
    OUT PIO_STATUS_BLOCK    IoStatus,
    IN PDEVICE_OBJECT       DeviceObject)
{
    PEXT2_FCB   Fcb = NULL;
    BOOLEAN     Status = FALSE;
    BOOLEAN     Locked = FALSE;

    Fcb = (PEXT2_FCB) FileObject->FsContext;
    if (Fcb == NULL)
        return FALSE;

    __try {

        FsRtlEnterFileSystem();

        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
               (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

        if (IsFlagOn(Fcb->Vcb->Flags, VCB_READ_ONLY)) {
            __leave;
        }

        ExAcquireResourceSharedLite(&Fcb->MainResource, TRUE);
        Locked = TRUE;

        if (IsEndOfFile(*FileOffset) || ((LONGLONG)(Fcb->Inode->i_size) <
                                         (FileOffset->QuadPart + Length)) ) {
        } else {
            ExReleaseResourceLite(&Fcb->MainResource);
            Locked = FALSE;
            Status = FsRtlCopyWrite(FileObject, FileOffset, Length, Wait,
                                    LockKey, Buffer, IoStatus, DeviceObject);
        }

    } __finally {

        if (Locked) {
            ExReleaseResourceLite(&Fcb->MainResource);
        }

        FsRtlExitFileSystem();
    }

    DEBUG(DL_IO, ("Ext2FastIoWrite: %wZ Offset: %I64xh Length: %xh Key: %xh Status=%d\n",
                   &Fcb->Mcb->ShortName,  FileOffset->QuadPart, Length, LockKey, Status));

    return Status;
}
TFile& TFile::ReadStrings(KStrings& RStrings, bool bClearFirst)
{
	DEBUG_VERIFY_ALLOCATION;

	DEBUG_VERIFY(IsOpen());

	if(!(m_flOpenFlags & FOF_READ) || !(m_flOpenFlags & FOF_TEXT))
		INITIATE_FAILURE;

	if(bClearFirst)
		RStrings.Clear();
	
	while(!IsEndOfFile())
		ReadString(*RStrings.AddLast());

	return *this;
}
	std::string DesktopFileHandle::ReadLine()
	{
		{
			std::lock_guard<std::recursive_mutex> recLock(mMutex);
			if (!bIsOpen)
				throw std::exception("File is not open");
		}

		if (IsEndOfFile())
			throw std::exception("End of Stream encountered.");

		std::string str;
		
		std::lock_guard<std::recursive_mutex> recLock(mMutex);
		std::getline(mFile, str);
		
		return str;
	}
// -----------------------------------------------------------------------------
// CUpnpHttpFileAccess::GetL
//
// -----------------------------------------------------------------------------
//
TBool CUpnpHttpFileAccess::GetL( TPtr8& aPointer, TInt aBytesToSend )
{
    LOGS1H( aHandle, "%i, CUpnpHttpFileAccess::GetL", this );
    if ( iFileToServe->Compare( *iOpenedFile ) ) // ignore if the same file
    {
        if ( iOpen )
        {
            iTargetFile.Close( );
        }
        iOpen = EFalse;
    }

    if ( !iOpen )
    {
        User::LeaveIfError( iTargetFile.Open( iFsSession, *iFileToServe,
                                              EFileRead|EFileShareReadersOnly ) );
        HBufC* tmp = iFileToServe->AllocL( );
        delete iOpenedFile;
        iOpenedFile = tmp;
        iOpen = ETrue;
    }

    User::LeaveIfError( iTargetFile.Seek( ESeekStart, iPosInFile ) );

    TInt BytesToRead = aBytesToSend;

    // Get min value from iEndPosInFile and buffer length
    // iEndPosInFile + - iPosInFile 1 because indicated byte should also be included
    if ( EndPosOfFile( ) != KErrNotFound )
        BytesToRead = (EndPosOfFile( ) - iPosInFile + 1) < BytesToRead
                      ? (EndPosOfFile( ) - iPosInFile + 1) : BytesToRead;

    LOGS1( "BytesToRead: %d", BytesToRead );

    User::LeaveIfError( iTargetFile.Read( aPointer, BytesToRead ) );
    iPosInFile = iPosInFile + aPointer.Length( );

    return IsEndOfFile();
}
// Интерпретировать следующий токен
bool EscInterpreter::InterpretNext()
{
    if (IsEndOfFile()) return false;

    unsigned char ch = GetNextByte();
    switch (ch)
    {
    case 0/*NUL*/: case 7/*BEL*/: case 17/*DC1*/: case 19/*DC3*/: case 127/*DEL*/:
        break; // Игнорируемые коды
    case 24/*CAN*/:
        m_endofpage = true;
        m_x = m_y = 0;
        return false; //Конец страницы
    case 8/*BS*/: // Backspace - сдвиг на 1 символ назад
        m_x -= m_shiftx;  if (m_x < 0) m_x = 0;
        break;
    case 9/*HT*/: // Горизонтальная табуляция - реализован частный случай
        //NOTE: переустановка позиций табуляции игнорируется
        m_x += m_shiftx * 8;
        m_x = (m_x / (m_shiftx * 8)) * (m_shiftx * 8);
        break;
    case 10/*LF*/: // Line Feed - сдвиг к следующей строке
        m_y += m_shifty;
        return true;
    case 11/*VT*/: //Вертикальная табуляция - в частном случае удовлетворяет описанию.
        //NOTE: Переустановка позиций табуляции игнорируется
        m_x = 0;  m_y += m_shifty;
        return true;
    case 12/*FF*/: // Form Feed - !!! доделать
        m_endofpage = true;
        m_x = m_y = 0;
        return false;
    case 13/*CR*/: // Carriage Return - возврат каретки
        m_x = 0;
        break;
    case 14/*SO*/: // Включение шрифта вразрядку
        m_fontsp = true;
        UpdateShiftX();
        break;
    case 15/*SI*/: // Включение сжатого шрифта (17.1 символов на дюйм)
        m_fontks = true;
        UpdateShiftX();
        break;
    case 18/*DC2*/: // Выключение сжатого шрифта
        m_fontks = false;
        UpdateShiftX();
        break;
    case 20/*DC4*/: // Выключение шрифта вразрядку
        m_fontsp = false;
        UpdateShiftX();
        break;
    case 27/*ESC*/:  //Expanded Function Codes
        return InterpretEscape();

        /* иначе "напечатать" символ */
    default:
        PrintCharacter(ch);
        m_x += m_shiftx;
        break;
    }

    return true;
}
Exemple #6
0
NTSTATUS
FFSWriteFile(
	IN PFFS_IRP_CONTEXT IrpContext)
{
	NTSTATUS            Status = STATUS_UNSUCCESSFUL;

	PFFS_VCB            Vcb  = NULL;
	PFFS_FCB            Fcb  = NULL;
	PFFS_CCB            Ccb =  NULL;
	PFILE_OBJECT        FileObject  = NULL;
	PFILE_OBJECT        CacheObject;

	PDEVICE_OBJECT      DeviceObject  = NULL;

	PIRP                Irp  = NULL;
	PIO_STACK_LOCATION  IoStackLocation  = NULL;

	ULONG               Length;
	ULONG               ReturnedLength = 0;
	LARGE_INTEGER       ByteOffset;

	BOOLEAN             PagingIo;
	BOOLEAN             Nocache;
	BOOLEAN             SynchronousIo;
	BOOLEAN             MainResourceAcquired = FALSE;
	BOOLEAN             PagingIoResourceAcquired = FALSE;

	BOOLEAN             bNeedExtending = FALSE;
	BOOLEAN             bAppendFile = FALSE;

	BOOLEAN             bDeferred = FALSE;

	PUCHAR              Buffer = NULL;

	__try
	{
		ASSERT(IrpContext);

		ASSERT((IrpContext->Identifier.Type == FFSICX) &&
				(IrpContext->Identifier.Size == sizeof(FFS_IRP_CONTEXT)));

		DeviceObject = IrpContext->DeviceObject;

		Vcb = (PFFS_VCB)DeviceObject->DeviceExtension;

		ASSERT(Vcb != NULL);

		ASSERT((Vcb->Identifier.Type == FFSVCB) &&
				(Vcb->Identifier.Size == sizeof(FFS_VCB)));

		FileObject = IrpContext->FileObject;

		Fcb = (PFFS_FCB)FileObject->FsContext;

		ASSERT(Fcb);

		ASSERT((Fcb->Identifier.Type == FFSFCB) &&
				(Fcb->Identifier.Size == sizeof(FFS_FCB)));

		Ccb = (PFFS_CCB)FileObject->FsContext2;

		Irp = IrpContext->Irp;

		IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

		Length = IoStackLocation->Parameters.Write.Length;
		ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;

		PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
		Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
		SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);

		FFSPrint((DBG_INFO, "FFSWriteFile: Off=%I64xh Len=%xh Paging=%xh Nocache=%xh\n",
					ByteOffset.QuadPart, Length, PagingIo, Nocache));

		/*
		if (IsFlagOn(Fcb->Flags, FCB_FILE_DELETED))
		{
			Status = STATUS_FILE_DELETED;
			__leave;
		}

		if (IsFlagOn(Fcb->Flags, FCB_DELETE_PENDING))
		{
			Status = STATUS_DELETE_PENDING;
			__leave;
		}
		*/

		if (Length == 0)
		{
			Irp->IoStatus.Information = 0;
			Status = STATUS_SUCCESS;
			__leave;
		}

		if (Nocache &&
				(ByteOffset.LowPart & (SECTOR_SIZE - 1) ||
				 Length & (SECTOR_SIZE - 1)))
		{
			Status = STATUS_INVALID_PARAMETER;
			__leave;
		}

		if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC))
		{
			ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
			Status = STATUS_PENDING;
			__leave;
		}

#if FALSE
		if (!Nocache)
		{
			BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
			BOOLEAN bWait  = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
			BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);

			if (!CcCanIWrite(
						FileObject,
						Length,
						(bWait && bQueue),
						bAgain))
			{
				SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);

				CcDeferWrite(FileObject,
						(PCC_POST_DEFERRED_WRITE)FFSDeferWrite,
						IrpContext,
						Irp,
						Length,
						bAgain);

				bDeferred = TRUE;

				FFSBreakPoint();

				Status = STATUS_PENDING;
				__leave;
			}
		}

#endif

		if (IsEndOfFile(ByteOffset))
		{
			bAppendFile = TRUE;
			ByteOffset.QuadPart = Fcb->Header.FileSize.QuadPart;
		}

		if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY) && !PagingIo)
		{
			Status = STATUS_INVALID_DEVICE_REQUEST;
			__leave;
		}

		//
		//  Do flushing for such cases
		//
		if (Nocache && !PagingIo && (Fcb->SectionObject.DataSectionObject != NULL)) 
		{
			ExAcquireResourceExclusive(&Fcb->MainResource, 
					IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));

			MainResourceAcquired = TRUE;

			ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
			ExReleaseResource(&Fcb->PagingIoResource);

			CcFlushCache(&(Fcb->SectionObject),
					&ByteOffset,
					Length,
					&(Irp->IoStatus));
			ClearFlag(Fcb->Flags, FCB_FILE_MODIFIED);

			if (!NT_SUCCESS(Irp->IoStatus.Status)) 
			{
				Status = Irp->IoStatus.Status;
				__leave;
			}

			ExAcquireSharedStarveExclusive(&Fcb->PagingIoResource, TRUE);
			ExReleaseResource(&Fcb->PagingIoResource);

			CcPurgeCacheSection(&(Fcb->SectionObject),
					(PLARGE_INTEGER)&(ByteOffset),
					Length,
					FALSE);

			ExReleaseResource(&Fcb->MainResource);
			MainResourceAcquired = FALSE;
		}

		if (!PagingIo)
		{
			if (!ExAcquireResourceExclusiveLite(
						&Fcb->MainResource,
						IrpContext->IsSynchronous))
			{
				Status = STATUS_PENDING;
				__leave;
			}

			MainResourceAcquired = TRUE;
		}
		else
		{
			/*
			ULONG ResShCnt, ResExCnt; 
			ResShCnt = ExIsResourceAcquiredSharedLite(&Fcb->PagingIoResource);
			ResExCnt = ExIsResourceAcquiredExclusiveLite(&Fcb->PagingIoResource);

			FFSPrint((DBG_USER, "FFSWriteFile: Inode=%xh %S PagingIo: %xh:%xh Synchronous=%xh\n",
			Fcb->FFSMcb->Inode, Fcb->FFSMcb->ShortName.Buffer, ResShCnt, ResExCnt, IrpContext->IsSynchronous));
			*/
			if (!ExAcquireResourceSharedLite(
						&Fcb->PagingIoResource,
						IrpContext->IsSynchronous))
			{
				Status = STATUS_PENDING;
				__leave;
			}

			PagingIoResourceAcquired = TRUE;
		}

		if (!PagingIo)
		{
			if (!FsRtlCheckLockForWriteAccess(
						&Fcb->FileLockAnchor,
						Irp))
			{
				Status = STATUS_FILE_LOCK_CONFLICT;
				__leave;
			}
		}

		if (Nocache)
		{
			if ((ByteOffset.QuadPart + Length) >
					Fcb->Header.AllocationSize.QuadPart)
			{
				if (ByteOffset.QuadPart >= 
						Fcb->Header.AllocationSize.QuadPart)
				{
					Status = STATUS_SUCCESS;
					Irp->IoStatus.Information = 0;
					__leave;
				}
				else
				{
					if (Length > (ULONG)(Fcb->Header.AllocationSize.QuadPart
								- ByteOffset.QuadPart))
					{
						Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart
								- ByteOffset.QuadPart);
					}
				}
			}
		}

		if (!Nocache)
		{
			if (FlagOn(Fcb->FFSMcb->FileAttr, FILE_ATTRIBUTE_DIRECTORY))
			{
				__leave;
			}

			if (FileObject->PrivateCacheMap == NULL)
			{
				CcInitializeCacheMap(
						FileObject,
						(PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
						FALSE,
						&FFSGlobal->CacheManagerCallbacks,
						Fcb);

				CcSetReadAheadGranularity(
						FileObject,
						READ_AHEAD_GRANULARITY);

				CcSetFileSizes(
						FileObject, 
						(PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
			}

			CacheObject = FileObject;

			//
			//  Need extending the size of inode ?
			//
			if ((bAppendFile) || ((ULONG)(ByteOffset.QuadPart + Length) >
						(ULONG)(Fcb->Header.FileSize.QuadPart)))
			{

				LARGE_INTEGER   ExtendSize;
				LARGE_INTEGER   FileSize;

				bNeedExtending = TRUE;
				FileSize = Fcb->Header.FileSize;
				ExtendSize.QuadPart = (LONGLONG)(ByteOffset.QuadPart + Length);

				if (ExtendSize.QuadPart > Fcb->Header.AllocationSize.QuadPart)
				{
					if (!FFSExpandFile(IrpContext, Vcb, Fcb, &ExtendSize))
					{
						Status = STATUS_INSUFFICIENT_RESOURCES;
						__leave;
					}
				}

				{
					Fcb->Header.FileSize.QuadPart = ExtendSize.QuadPart;
					Fcb->dinode1->di_size = (ULONG)ExtendSize.QuadPart;
				}

				if (FileObject->PrivateCacheMap)
				{
					CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));

					if (ByteOffset.QuadPart > FileSize.QuadPart)
					{
						FFSZeroHoles(IrpContext, Vcb, FileObject, FileSize.QuadPart, 
								ByteOffset.QuadPart - FileSize.QuadPart);
					}

					if (Fcb->Header.AllocationSize.QuadPart > ExtendSize.QuadPart)
					{
						FFSZeroHoles(IrpContext, Vcb, FileObject, ExtendSize.QuadPart, 
								Fcb->Header.AllocationSize.QuadPart - ExtendSize.QuadPart);
					}
				}

				if (FFSv1SaveInode(IrpContext, Vcb, Fcb->FFSMcb->Inode, Fcb->dinode1))
				{
					Status = STATUS_SUCCESS;
				}

				FFSNotifyReportChange(
						IrpContext,
						Vcb,
						Fcb,
						FILE_NOTIFY_CHANGE_SIZE,
						FILE_ACTION_MODIFIED);
			}

			if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL))
			{
				CcPrepareMdlWrite(
						CacheObject,
						(&ByteOffset),
						Length,
						&Irp->MdlAddress,
						&Irp->IoStatus);

				Status = Irp->IoStatus.Status;
			}
			else
			{
				Buffer = FFSGetUserBuffer(Irp);

				if (Buffer == NULL)
				{
					FFSBreakPoint();
					Status = STATUS_INVALID_USER_BUFFER;
					__leave;
				}

				if (!CcCopyWrite(
							CacheObject,
							(PLARGE_INTEGER)&ByteOffset,
							Length,
							IrpContext->IsSynchronous,
							Buffer))
				{
					Status = STATUS_PENDING;
					__leave;
				}

				Status = Irp->IoStatus.Status;
			}

			if (NT_SUCCESS(Status))
			{
				Irp->IoStatus.Information = Length;

				if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK))
				{
					FFSPrint((DBG_USER, "FFSWriteFile is starting FlushingDpc...\n"));
					FFSStartFloppyFlushDpc(Vcb, Fcb, FileObject);
				}
			}
		}
		else
		{
			ReturnedLength = Length;

			Status = FFSLockUserBuffer(
					IrpContext->Irp,
					Length,
					IoReadAccess);

			if (!NT_SUCCESS(Status))
			{
				__leave;
			}

			Irp->IoStatus.Status = STATUS_SUCCESS;
			Irp->IoStatus.Information = Length;

			Status = 
				FFSv1WriteInode(
						IrpContext,
						Vcb,
						Fcb->dinode1,
						(ULONGLONG)(ByteOffset.QuadPart),
						NULL,
						Length,
						TRUE,
						&ReturnedLength);

			Irp = IrpContext->Irp;

		}
	}

	__finally
	{
		if (PagingIoResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Fcb->PagingIoResource,
					ExGetCurrentResourceThread());
		}

		if (MainResourceAcquired)
		{
			ExReleaseResourceForThreadLite(
					&Fcb->MainResource,
					ExGetCurrentResourceThread());
		}

		if (!IrpContext->ExceptionInProgress)
		{
			if (Irp)
			{
				if (Status == STATUS_PENDING)
				{
					if (!bDeferred)
					{
						Status = FFSLockUserBuffer(
									IrpContext->Irp,
									Length,
									IoReadAccess);

						if (NT_SUCCESS(Status))
						{
							Status = FFSQueueRequest(IrpContext);
						}
						else
						{
							FFSCompleteIrpContext(IrpContext, Status);
						}
					}
				}
				else
				{
					if (NT_SUCCESS(Status))
					{
						if (SynchronousIo && !PagingIo)
						{
							FileObject->CurrentByteOffset.QuadPart =
								ByteOffset.QuadPart + Irp->IoStatus.Information;
						}

						if (!PagingIo)
						{
							SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
							SetFlag(Fcb->Flags, FCB_FILE_MODIFIED);
						}
					}

					FFSCompleteIrpContext(IrpContext, Status);
				}
			}
			else
			{
				FFSFreeIrpContext(IrpContext);
			}
		}
	}

	return Status;

}
Exemple #7
0
NTSTATUS
Ext2WriteFile(IN PEXT2_IRP_CONTEXT IrpContext)
{
    NTSTATUS            Status = STATUS_UNSUCCESSFUL;

    PEXT2_VCB           Vcb;
    PEXT2_FCB           Fcb;
    PEXT2_CCB           Ccb;
    PFILE_OBJECT        FileObject;
    PFILE_OBJECT        CacheObject;

    PDEVICE_OBJECT      DeviceObject;

    PIRP                Irp;
    PIO_STACK_LOCATION  IoStackLocation;

    ULONG               Length;
    LARGE_INTEGER       ByteOffset;
    ULONG               ReturnedLength = 0;

    BOOLEAN             OpPostIrp = FALSE;
    BOOLEAN             PagingIo;
    BOOLEAN             Nocache;
    BOOLEAN             SynchronousIo;

    BOOLEAN             RecursiveWriteThrough = FALSE;
    BOOLEAN             MainResourceAcquired = FALSE;
    BOOLEAN             PagingIoResourceAcquired = FALSE;

    BOOLEAN             bDeferred = FALSE;
    BOOLEAN             FileSizesChanged = FALSE;

    PUCHAR              Buffer;

    __try {

        ASSERT(IrpContext);
        ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
               (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));

        DeviceObject = IrpContext->DeviceObject;
        Vcb = (PEXT2_VCB) DeviceObject->DeviceExtension;
        ASSERT(Vcb != NULL);
        ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
               (Vcb->Identifier.Size == sizeof(EXT2_VCB)));

        FileObject = IrpContext->FileObject;
        Fcb = (PEXT2_FCB) FileObject->FsContext;
        Ccb = (PEXT2_CCB) FileObject->FsContext2;
        ASSERT(Fcb);
        ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
               (Fcb->Identifier.Size == sizeof(EXT2_FCB)));

        Irp = IrpContext->Irp;
        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

        Length = IoStackLocation->Parameters.Write.Length;
        ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;

        PagingIo = IsFlagOn(Irp->Flags, IRP_PAGING_IO);
        Nocache = IsFlagOn(Irp->Flags, IRP_NOCACHE);
        SynchronousIo = IsFlagOn(FileObject->Flags, FO_SYNCHRONOUS_IO);

        if (PagingIo) {
            ASSERT(Nocache);
        }

        DEBUG(DL_INF, ("Ext2WriteFile: %wZ Offset=%I64xh Length=%xh Paging=%xh Nocache=%xh\n",
                       &Fcb->Mcb->ShortName, ByteOffset.QuadPart, Length, PagingIo, Nocache));

        if (IsSpecialFile(Fcb)) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        if (IsFileDeleted(Fcb->Mcb) ||
            (IsSymLink(Fcb) && IsFileDeleted(Fcb->Mcb->Target)) ) {
            Status = STATUS_FILE_DELETED;
            __leave;
        }

        if (Length == 0) {
            Irp->IoStatus.Information = 0;
            Status = STATUS_SUCCESS;
            __leave;
        }

        if (Nocache && ( (ByteOffset.LowPart & (SECTOR_SIZE - 1)) ||
                         (Length & (SECTOR_SIZE - 1))) ) {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC)) {
            ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
            Status = STATUS_PENDING;
            __leave;
        }

        if (!Nocache) {

            BOOLEAN bAgain = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
            BOOLEAN bWait  = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
            BOOLEAN bQueue = IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_REQUEUED);

            if ( !CcCanIWrite(
                        FileObject,
                        Length,
                        (bWait && bQueue),
                        bAgain ) ) {

                Status = Ext2LockUserBuffer(
                             IrpContext->Irp,
                             Length,
                             IoReadAccess);

                if (NT_SUCCESS(Status)) {
                    SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_DEFERRED);
                    CcDeferWrite( FileObject,
                                  (PCC_POST_DEFERRED_WRITE)Ext2DeferWrite,
                                  IrpContext,
                                  Irp,
                                  Length,
                                  bAgain );
                    bDeferred = TRUE;
                    Status = STATUS_PENDING;
                    __leave;
                }
            }
        }

        if (IsEndOfFile(ByteOffset)) {
            ByteOffset.QuadPart = Fcb->Header.FileSize.QuadPart;
        }

        if (IsDirectory(Fcb) && !PagingIo) {
            Status = STATUS_INVALID_DEVICE_REQUEST;
            __leave;
        }

        if (IsFlagOn(Irp->Flags, IRP_SYNCHRONOUS_PAGING_IO) && !IrpContext->IsTopLevel) {

            PIRP TopIrp;

            TopIrp = IoGetTopLevelIrp();

            if ( (ULONG_PTR)TopIrp > FSRTL_MAX_TOP_LEVEL_IRP_FLAG &&
                    NodeType(TopIrp) == IO_TYPE_IRP) {

                PIO_STACK_LOCATION IrpStack;

                IrpStack = IoGetCurrentIrpStackLocation(TopIrp);

                if ((IrpStack->MajorFunction == IRP_MJ_WRITE) &&
                        (IrpStack->FileObject->FsContext == FileObject->FsContext)) {

                    RecursiveWriteThrough = TRUE;
                }
            }
        }

        //
        //  Do flushing for such cases
        //
        if (Nocache && !PagingIo && Ccb != NULL &&
                (Fcb->SectionObject.DataSectionObject != NULL))  {

            MainResourceAcquired =
                ExAcquireResourceExclusiveLite( &Fcb->MainResource,
                                                IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));

            ExAcquireSharedStarveExclusive( &Fcb->PagingIoResource, TRUE);
            ExReleaseResourceLite(&Fcb->PagingIoResource);

            CcFlushCache( &(Fcb->SectionObject),
                          &ByteOffset,
                          CEILING_ALIGNED(ULONG, Length, BLOCK_SIZE),
                          &(Irp->IoStatus));
            ClearLongFlag(Fcb->Flags, FCB_FILE_MODIFIED);

            if (!NT_SUCCESS(Irp->IoStatus.Status)) {
                Status = Irp->IoStatus.Status;
                __leave;
            }

            ExAcquireSharedStarveExclusive( &Fcb->PagingIoResource, TRUE);
            ExReleaseResourceLite(&Fcb->PagingIoResource);

            CcPurgeCacheSection( &(Fcb->SectionObject),
                                 (PLARGE_INTEGER)&(ByteOffset),
                                 CEILING_ALIGNED(ULONG, Length, BLOCK_SIZE),
                                 FALSE );

            if (MainResourceAcquired) {
                ExReleaseResourceLite(&Fcb->MainResource);
                MainResourceAcquired = FALSE;
            }
        }

        if (!PagingIo) {

            if (!ExAcquireResourceExclusiveLite(
                        &Fcb->MainResource,
                        IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
                Status = STATUS_PENDING;
                __leave;
            }

            MainResourceAcquired = TRUE;

            if (!FsRtlCheckLockForWriteAccess(
                        &Fcb->FileLockAnchor,
                        Irp         )) {
                Status = STATUS_FILE_LOCK_CONFLICT;
                __leave;
            }

        } else {

            if (!ExAcquireResourceSharedLite(
                        &Fcb->PagingIoResource,
                        IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
                Status = STATUS_PENDING;
                __leave;
            }

            PagingIoResourceAcquired = TRUE;
        }

        if (!IsDirectory(Fcb) && Ccb != NULL) {

            Status = FsRtlCheckOplock( &Fcb->Oplock,
                                       Irp,
                                       IrpContext,
                                       Ext2OplockComplete,
                                       Ext2LockIrp );

            if (Status != STATUS_SUCCESS) {
                OpPostIrp = TRUE;
                __leave;
            }

            //
            //  Set the flag indicating if Fast I/O is possible
            //

            Fcb->Header.IsFastIoPossible = Ext2IsFastIoPossible(Fcb);
        }

        if (PagingIo) {

            if ( (ByteOffset.QuadPart + Length) > Fcb->Header.AllocationSize.QuadPart) {

                if ( ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {

                    Status = STATUS_END_OF_FILE;
                    Irp->IoStatus.Information = 0;
                    __leave;

                } else {

                    Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - ByteOffset.QuadPart);
                }
            }

        } else {

            if (IsDirectory(Fcb)) {
                __leave;
            }

            //
            //  Extend the inode size when the i/o is beyond the file end ?
            //

            if ((ByteOffset.QuadPart + Length) > Fcb->Header.FileSize.QuadPart) {

                LARGE_INTEGER AllocationSize, Last;

                Last.QuadPart = Fcb->Header.AllocationSize.QuadPart;
                AllocationSize.QuadPart = (LONGLONG)(ByteOffset.QuadPart + Length);
                AllocationSize.QuadPart = CEILING_ALIGNED(ULONGLONG,
                                          (ULONGLONG)AllocationSize.QuadPart,
                                          (ULONGLONG)BLOCK_SIZE);
                Status = Ext2ExpandFile(IrpContext, Vcb, Fcb->Mcb, &AllocationSize);
                if (AllocationSize.QuadPart > Last.QuadPart) {
                    Fcb->Header.AllocationSize.QuadPart = AllocationSize.QuadPart;
                    SetLongFlag(Fcb->Flags, FCB_ALLOC_IN_WRITE);
                }

                if (ByteOffset.QuadPart >= Fcb->Header.AllocationSize.QuadPart) {
                    if (NT_SUCCESS(Status)) {
                        DbgBreak();
                        Status = STATUS_UNSUCCESSFUL;
                    }
                    __leave;
                }

                if (ByteOffset.QuadPart + Length > Fcb->Header.AllocationSize.QuadPart) {
                    Length = (ULONG)(Fcb->Header.AllocationSize.QuadPart - ByteOffset.QuadPart);
                }

                Fcb->Header.FileSize.QuadPart = Fcb->Inode->i_size = ByteOffset.QuadPart + Length;
                Ext2SaveInode(IrpContext, Vcb, Fcb->Inode);

                if (CcIsFileCached(FileObject)) {
                    CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
                    if (AllocationSize.QuadPart > Last.QuadPart)
                        CcZeroData(FileObject, &Last, &AllocationSize, FALSE);
                }

                FileSizesChanged = TRUE;

                if (Fcb->Header.FileSize.QuadPart >= 0x80000000 &&
                        !IsFlagOn(SUPER_BLOCK->s_feature_ro_compat, EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
                    SetFlag(SUPER_BLOCK->s_feature_ro_compat, EXT2_FEATURE_RO_COMPAT_LARGE_FILE);
                    Ext2SaveSuper(IrpContext, Vcb);
                }
                DEBUG(DL_IO, ("Ext2WriteFile: expanding %wZ to FS: %I64xh FA: %I64xh\n",
                              &Fcb->Mcb->ShortName, Fcb->Header.FileSize.QuadPart,
                              Fcb->Header.AllocationSize.QuadPart));
            }
        }

        ReturnedLength = Length;

        if (!Nocache) {

            if (FileObject->PrivateCacheMap == NULL) {
                CcInitializeCacheMap(
                    FileObject,
                    (PCC_FILE_SIZES)(&Fcb->Header.AllocationSize),
                    FALSE,
                    &Ext2Global->CacheManagerCallbacks,
                    Fcb );

                CcSetReadAheadGranularity(
                    FileObject,
                    READ_AHEAD_GRANULARITY );
            }

            CacheObject = FileObject;

            if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {

                CcPrepareMdlWrite(
                    CacheObject,
                    (&ByteOffset),
                    Length,
                    &Irp->MdlAddress,
                    &Irp->IoStatus );

                Status = Irp->IoStatus.Status;

            } else {

                Buffer = Ext2GetUserBuffer(Irp);
                if (Buffer == NULL) {
                    DbgBreak();
                    Status = STATUS_INVALID_USER_BUFFER;
                    __leave;
                }

                if (!CcCopyWrite(
                            CacheObject,
                            (PLARGE_INTEGER)&ByteOffset,
                            Length,
                            IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT),
                            Buffer  )) {
                    Status = STATUS_PENDING;
                    DbgBreak();
                    __leave;
                }

                Status = STATUS_SUCCESS;
            }

            if (NT_SUCCESS(Status)) {
                Irp->IoStatus.Information = Length;
                if (IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK)) {
                    DEBUG(DL_FLP, ("Ext2WriteFile is starting FlushingDpc...\n"));
                    Ext2StartFloppyFlushDpc(Vcb, Fcb, FileObject);
                }
            }

        } else {

            if (!PagingIo && CcIsFileCached(FileObject) && !RecursiveWriteThrough &&
                    Fcb->LazyWriterThread != PsGetCurrentThread() &&
                    ByteOffset.QuadPart > Fcb->Header.ValidDataLength.QuadPart) {

                Ext2ZeroHoles( IrpContext, Vcb, FileObject, Fcb->Header.ValidDataLength.QuadPart,
                               ByteOffset.QuadPart - Fcb->Header.ValidDataLength.QuadPart );
            }

            Status = Ext2LockUserBuffer(
                         IrpContext->Irp,
                         Length,
                         IoReadAccess );

            if (!NT_SUCCESS(Status)) {
                __leave;
            }

            Irp->IoStatus.Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = ReturnedLength;

            Status = Ext2WriteInode(
                         IrpContext,
                         Vcb,
                         Fcb->Mcb,
                         (ULONGLONG)(ByteOffset.QuadPart),
                         NULL,
                         ReturnedLength,
                         TRUE,
                         &Length
                     );

            Irp = IrpContext->Irp;
        }

        /* Update files's ValidDateLength */
        if (NT_SUCCESS(Status) && !PagingIo && CcIsFileCached(FileObject) &&
                !RecursiveWriteThrough && Fcb->LazyWriterThread != PsGetCurrentThread()) {

            if (Fcb->Header.ValidDataLength.QuadPart < ByteOffset.QuadPart + Length) {
                Fcb->Header.ValidDataLength.QuadPart = ByteOffset.QuadPart + Length;
                FileSizesChanged = TRUE;
            }

            if (Fcb->Mcb->Inode.i_size < (loff_t) (Fcb->Header.ValidDataLength.QuadPart)) {
                Fcb->Header.ValidDataLength.QuadPart = Fcb->Mcb->Inode.i_size;
                FileSizesChanged = TRUE;
            }

            if (CcIsFileCached(FileObject)) {
                CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->Header.AllocationSize)));
            }

            DEBUG(DL_IO, ("Ext2WriteFile: %wZ written FS: %I64xh FA: %I64xh BO: %I64xh LEN: %u\n",
                          &Fcb->Mcb->ShortName, Fcb->Header.FileSize.QuadPart,
                          Fcb->Header.AllocationSize.QuadPart, ByteOffset.QuadPart, Length));
        }

        if (FileSizesChanged) {
            Ext2NotifyReportChange( IrpContext,  Vcb, Fcb->Mcb,
                                    FILE_NOTIFY_CHANGE_SIZE,
                                    FILE_ACTION_MODIFIED );
        }

    } __finally {

        if (Irp) {
            if (PagingIoResourceAcquired) {
                ExReleaseResourceLite(&Fcb->PagingIoResource);
            }

            if (MainResourceAcquired) {
                ExReleaseResourceLite(&Fcb->MainResource);
            }
        }

        if (!OpPostIrp && !IrpContext->ExceptionInProgress) {

            if (Irp) {

                if (Status == STATUS_PENDING ||
                        Status == STATUS_CANT_WAIT ) {

                    if (!bDeferred) {
                        Status = Ext2QueueRequest(IrpContext);
                    }

                } else {

                    if (NT_SUCCESS(Status)) {

                        if (SynchronousIo && !PagingIo) {
                            FileObject->CurrentByteOffset.QuadPart =
                                ByteOffset.QuadPart + Irp->IoStatus.Information;
                        }

                        if (!PagingIo) {
                            SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
                            SetLongFlag(Fcb->Flags, FCB_FILE_MODIFIED);
                        }
                    }

                    Ext2CompleteIrpContext(IrpContext, Status);
                }
            } else {
                Ext2FreeIrpContext(IrpContext);
            }
        }
    }

    DEBUG(DL_IO, ("Ext2WriteFile: %wZ written at Offset=%I64xh Length=%xh PagingIo=%d Nocache=%d "
                  "RetLen=%xh VDL=%I64xh FileSize=%I64xh i_size=%I64xh Status=%xh\n",
                  &Fcb->Mcb->ShortName, ByteOffset, Length, PagingIo, Nocache, ReturnedLength,
                  Fcb->Header.ValidDataLength.QuadPart,Fcb->Header.FileSize.QuadPart,
                  Fcb->Inode->i_size, Status));

    return Status;
}
Token* LexicalAnalyzer::GetNextToken()
{
    if(IsEndOfFile())
        return EndOfFileToken();

    char c = NextChar();
    m_lexemeBegin = m_forward;
    m_dfa->Reset();

    int m_currentTokenTypeId = TOKEN_Unrecognized;
    while(true)
    {
        m_currentTokenTypeId = m_dfa->Move(c);
        if(m_currentTokenTypeId == TOKEN_Unrecognized)
        {
            c = NextChar();
        }
        else
        {
            break;
        }
    }

    Retract();

    if(IsIgnoredToken(m_currentTokenTypeId))
    {
        return GetNextToken();
    }
    else
    {
        Token*                      token;
        string                      lexeme;
        TokenValue*                 tokenValue;
        vector<PlainCharacter*>&    buffer = m_buffer->InnerBuffer();

        m_buffer->ExtractString(m_lexemeBegin, m_forward - m_lexemeBegin + 1, lexeme);

        tokenValue = new TokenValue("", buffer[m_lexemeBegin]->Row, buffer[m_lexemeBegin]->Column);
        token = new Token(m_currentTokenTypeId, tokenValue);

        if(IsCompositeToken(m_currentTokenTypeId))
        {
            if(m_reservedWordsToTokenTypeIdMap.find(lexeme) != m_reservedWordsToTokenTypeIdMap.end())
            {
                token->TypeId = g_TokenTypesMap[m_reservedWordsToTokenTypeIdMap[lexeme]]->Id;
                m_recognizedTokens.push_back(token);
                return token;
            }
        }

        if(IsSpecialToken(m_currentTokenTypeId))
        {
            m_recognizedTokens.push_back(token);
            return token;
        }
        else if(IsIdentifierToken(m_currentTokenTypeId))
        {
            // save the index of the identifier in the symbol table
            token->Value->Data = m_symbolTable.size();
            m_symbolTable.push_back(token);
        }

        token->Value->Lexeme = lexeme;

        if(IsErrorToken(m_currentTokenTypeId))
        {
            OnFail(token);
        }

        m_recognizedTokens.push_back(token);
        return token;
    }
}