⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 create.c

📁 This is a ReiserFs file system driver for Windows NT/2000/XP/Vista.
💻 C
📖 第 1 页 / 共 4 页
字号:
NTSTATUS
RfsdCreate (IN PRFSD_IRP_CONTEXT IrpContext)
{
    PDEVICE_OBJECT      DeviceObject;
    PIRP                Irp;
    PIO_STACK_LOCATION  IrpSp;
    PRFSD_VCB           Vcb = 0;
    NTSTATUS            Status = STATUS_OBJECT_NAME_NOT_FOUND;
    PRFSD_FCBVCB        Xcb = NULL;

    DeviceObject = IrpContext->DeviceObject;

    Vcb = (PRFSD_VCB) DeviceObject->DeviceExtension;

    ASSERT(IsMounted(Vcb));
    
    Irp = IrpContext->Irp;
    
    IrpSp = IoGetCurrentIrpStackLocation(Irp);

    Xcb = (PRFSD_FCBVCB) (IrpSp->FileObject->FsContext);
    
    if (DeviceObject == RfsdGlobal->DeviceObject) {
        RfsdPrint((DBG_INFO, "RfsdCreate: Create on main device object.\n"));

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

        RfsdUnpinRepinnedBcbs(IrpContext);

        RfsdCompleteIrpContext(IrpContext, Status);        

        return Status;
    }
   
    __try {

        if (IsFlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
            Status = STATUS_ACCESS_DENIED;

            if (IsFlagOn(Vcb->Flags, VCB_DISMOUNT_PENDING)) {
                Status = STATUS_VOLUME_DISMOUNTED;
            }

            __leave;
        }

        if ( ((IrpSp->FileObject->FileName.Length == 0) &&
             (IrpSp->FileObject->RelatedFileObject == NULL)) || 
             (Xcb && Xcb->Identifier.Type == RFSDVCB)  ) {
            Status = RfsdCreateVolume(IrpContext, Vcb);
        } else {
            Status = RfsdCreateFile(IrpContext, Vcb);
        }

    } __finally {

        if (!IrpContext->ExceptionInProgress)  {
            RfsdUnpinRepinnedBcbs(IrpContext);
     
            RfsdCompleteIrpContext(IrpContext, Status);
        }
    }

    return Status;
}


#if DISABLED		// WRITE SUPPORT ONLY?
NTSTATUS
RfsdCreateInode(
    PRFSD_IRP_CONTEXT   IrpContext,
    PRFSD_VCB           Vcb,
    PRFSD_FCB           ParentFcb,
    ULONG               Type,
    ULONG               FileAttr,
    PUNICODE_STRING     FileName)
{

DbgBreak();

	NTSTATUS    Status;
    ULONG       Inode;
    ULONG       Group;

    RFSD_INODE  RfsdIno;

    RtlZeroMemory(&RfsdIno, sizeof(RFSD_INODE));

DbgBreak();
#if DISABLED
	 Group = (ParentFcb->RfsdMcb->Inode - 1) / BLOCKS_PER_GROUP;
#endif

    RfsdPrint(( DBG_INFO,
                "RfsdCreateInode: %S in %S(Key=%x,%xh)\n",
                FileName->Buffer, 
                ParentFcb->RfsdMcb->ShortName.Buffer, 
                ParentFcb->RfsdMcb->Key.k_dir_id, ParentFcb->RfsdMcb->Key.k_objectid));

    Status = RfsdNewInode(IrpContext, Vcb, Group,Type, &Inode);

    if (!NT_SUCCESS(Status)) {
        goto errorout;
    }

    Status = RfsdAddEntry(IrpContext, Vcb, ParentFcb, Type, Inode, FileName);

    if (!NT_SUCCESS(Status)) {
        DbgBreak();
        RfsdFreeInode(IrpContext, Vcb, Inode, Type);

        goto errorout;
    }

    RfsdSaveInode(IrpContext, Vcb, ParentFcb->RfsdMcb->Inode, ParentFcb->Inode);

    RfsdIno.i_ctime = ParentFcb->Inode->i_mtime;
    RfsdIno.i_mode =  ( S_IPERMISSION_MASK &
                        ParentFcb->Inode->i_mode );
    RfsdIno.i_uid = ParentFcb->Inode->i_uid;
    RfsdIno.i_gid = ParentFcb->Inode->i_gid;

    //~ RfsdIno.i_dir_acl = ParentFcb->Inode->i_dir_acl;
    //~ RfsdIno.i_file_acl = ParentFcb->Inode->i_file_acl;
    RfsdIno.u.i_generation = ParentFcb->Inode->u.i_generation;

    //~ RfsdIno.osd2 = ParentFcb->Inode->osd2;

    if (IsFlagOn(FileAttr, FILE_ATTRIBUTE_READONLY)) {
        RfsdSetReadOnly(RfsdIno.i_mode);
    }

    if (Type == RFSD_FT_DIR)  {
        RfsdIno.i_mode |= S_IFDIR;
        RfsdIno.i_links_count = 2;
    } else if (Type == RFSD_FT_REG_FILE) {
        RfsdIno.i_mode |= S_IFREG;
        RfsdIno.i_links_count = 1;
    } else {
        DbgBreak();
        RfsdIno.i_links_count = 1;
    }

    RfsdSaveInode(IrpContext, Vcb, Inode, &RfsdIno);

    RfsdPrint((DBG_INFO, "RfsdCreateInode: New Inode = %xh (Type=%xh)\n", Inode, Type));
            
errorout:

    return Status;
}
#endif

#if DISABLED
NTSTATUS
RfsdSupersedeOrOverWriteFile(
        PRFSD_IRP_CONTEXT IrpContext,
        PRFSD_VCB Vcb,
        PRFSD_FCB Fcb,
        ULONG     Disposition)
{
DbgBreak();

    LARGE_INTEGER   CurrentTime;
    LARGE_INTEGER   AllocationSize;
    NTSTATUS        Status = STATUS_SUCCESS;
    
    KeQuerySystemTime(&CurrentTime);

    AllocationSize.QuadPart = (LONGLONG)0;

    if (!MmCanFileBeTruncated(&(Fcb->SectionObject), &(AllocationSize))) {
        Status = STATUS_USER_MAPPED_FILE;
        return Status;
    }

DbgBreak();
#if DISABLED
    Status = RfsdTruncateFile(IrpContext, Vcb, Fcb, &AllocationSize);
#endif

    if (NT_SUCCESS(Status)) {			
        Fcb->Header.AllocationSize.QuadPart = 
        Fcb->Header.FileSize.QuadPart =  (LONGLONG) 0;

        Fcb->Inode->i_size = 0;

        if (S_ISREG(Fcb->Inode->i_mode)) {
			KdPrint(("Reminder: Fcb->Inode->i_size_high = 0;\n"));
            //~Fcb->Inode->i_size_high = 0;
        }

        if (Disposition == FILE_SUPERSEDE)
            Fcb->Inode->i_ctime = RfsdInodeTime(CurrentTime);

        Fcb->Inode->i_atime =
        Fcb->Inode->i_mtime = RfsdInodeTime(CurrentTime);
    } else {
        LARGE_INTEGER   iSize;

        iSize.QuadPart  =  (LONGLONG) Fcb->Inode->i_size;

        if (S_ISREG(Fcb->Inode->i_mode))
			KdPrint(("Reminder: Fcb->Inode->i_size_high = 0;\n"));
        //~    iSize.HighPart = (LONG)(Fcb->Inode->i_size_high);

        if (iSize.QuadPart > Fcb->Header.AllocationSize.QuadPart)
            iSize.QuadPart = Fcb->Header.AllocationSize.QuadPart;
    
        Fcb->Header.FileSize.QuadPart =  iSize.QuadPart;

        Fcb->Inode->i_size = iSize.LowPart;
        //~ Fcb->Inode->i_size_high = (ULONG) iSize.HighPart;
    }

    RfsdSaveInode(IrpContext, Vcb, Fcb->RfsdMcb->Inode, Fcb->Inode);

    return Status;
}
#endif

/**
 Searches to find if the name if is located in the dentry span within the block.

 STATUS_SUCCESS			if the name was not found, but processing should continue
 STATUS_EVENT_DONE		if the name was found, and processing should stop
*/
NTSTATUS
RfsdScanDirCallback(
	ULONG		BlockNumber,
	PVOID		pContext )
{
	PRFSD_SCANDIR_CALLBACK_CONTEXT	pCallbackContext = (PRFSD_SCANDIR_CALLBACK_CONTEXT) pContext;
	RFSD_KEY_IN_MEMORY				DirectoryKey;
	PUCHAR					pBlockBuffer			= NULL;
	PRFSD_ITEM_HEAD			pDirectoryItemHeader	= NULL;
	PUCHAR					pDirectoryItemBuffer	= NULL;
	NTSTATUS				Status;

	BOOLEAN					bFound = FALSE;
	PRFSD_DENTRY_HEAD		pPrevDentry = NULL;
	ULONG					idxDentryInSpan = 0;
	UNICODE_STRING          InodeFileName;
	USHORT                  InodeFileNameLength;
	InodeFileName.Buffer = NULL;

	RfsdPrint((DBG_FUNC, __FUNCTION__ " invoked on block %i\n", BlockNumber));


	__try {

	// Load the block
	pBlockBuffer = RfsdAllocateAndLoadBlock(pCallbackContext->Vcb, BlockNumber);
    if (!pBlockBuffer) { Status = STATUS_INSUFFICIENT_RESOURCES; __leave; }	

	// Construct the item key to search for
	DirectoryKey = *(pCallbackContext->pDirectoryKey);
	DirectoryKey.k_type = RFSD_KEY_TYPE_v2_DIRENTRY;

	// Get the item header and its information
	Status = RfsdFindItemHeaderInBlock(
		pCallbackContext->Vcb, &DirectoryKey, pBlockBuffer,
		( &pDirectoryItemHeader ),			//< 
		&CompareKeysWithoutOffset
	); 

	// If this block doesn't happen to contain a directory item, skip it.
	if ( (Status == STATUS_NO_SUCH_MEMBER) || !pDirectoryItemHeader )
	{ 
		KdPrint(("Block %i did not contain the appropriate diritem header\n", BlockNumber));
		Status = STATUS_SUCCESS; __leave; 
	}

			// Setup the item buffer
		pDirectoryItemBuffer = (PUCHAR) pBlockBuffer + pDirectoryItemHeader->ih_item_location;	



		// Allocate the unicode filename buffer
	    InodeFileName.Buffer = ExAllocatePool(PagedPool, (RFSD_NAME_LEN + 1) * 2 );
		if (!InodeFileName.Buffer) { Status = STATUS_INSUFFICIENT_RESOURCES; __leave; }


		while (!bFound && (idxDentryInSpan < pDirectoryItemHeader->u.ih_entry_count) ) {
            OEM_STRING OemName;	

			//
            // reading dir entries from Dcb
            //		
						
			PRFSD_DENTRY_HEAD	pCurrentDentry = (PRFSD_DENTRY_HEAD)  (pDirectoryItemBuffer + (idxDentryInSpan * sizeof(RFSD_DENTRY_HEAD)));

			// Skip the directory entry for the parent of the root directory (because it should not be shown, and has no stat data)
			// (NOTE: Any change made here should also be mirrored in RfsdDirControlCallback)
			if (pCurrentDentry->deh_dir_id == 0 /*&& pCurrentDentry->deh_objectid == 1*/)
			    { goto ProcessNextEntry; }

			// Retrieve the filename of the loaded directory entry from the buffer (encoded with the codepage)            	
			// NOTE: The filename is not gauranteed to be null-terminated, and so the end may implicitly be the start of the previous entry.
			OemName.Buffer			= (PUCHAR) pDirectoryItemBuffer + pCurrentDentry->deh_location;
			OemName.MaximumLength	= (pPrevDentry ? pPrevDentry->deh_location :			// The end of this entry is the start of the previous
													 pDirectoryItemHeader->ih_item_len		// Otherwise this is the first entry, the end of which is the end of the item.
									  ) -  pCurrentDentry->deh_location;
			OemName.Length			= RfsdStringLength(OemName.Buffer, OemName.MaximumLength);



			// Convert that name to unicode
			{
              InodeFileNameLength = (USHORT) RfsdOEMToUnicodeSize(&OemName) + 2;
              
			  // If the unicode InodeFileName.Buffer is not large enough, expand it
			  if (InodeFileName.MaximumLength < InodeFileNameLength)
			  {
				  // Free the existing buffer
				  if (InodeFileName.Buffer)  { ExFreePool(InodeFileName.Buffer); }

				  // Allocate a new larger buffer
				  InodeFileName.Buffer = ExAllocatePool(PagedPool, InodeFileNameLength );
				  if (!InodeFileName.Buffer) { Status = STATUS_INSUFFICIENT_RESOURCES; __leave; }
				  InodeFileName.MaximumLength = InodeFileNameLength;				  
			  }

              InodeFileName.Length = 0;
              
              RtlZeroMemory( InodeFileName.Buffer, InodeFileNameLength);
              
              Status = RfsdOEMToUnicode(
                              &InodeFileName,
                              &OemName    );

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


			// Compare it to the name we are searching for
            if (!RtlCompareUnicodeString(
				pCallbackContext->pTargetFilename,
                    &InodeFileName,
                    TRUE ))  {
				// This entry MATCHED!  Copy the matching dentry into the output field on the context
                bFound = TRUE;
				
				*(pCallbackContext->pMatchingIndex) = (pCallbackContext->idxCurrentDentry * sizeof(RFSD_DENTRY_HEAD));
                RtlCopyMemory(pCallbackContext->pMatchingDentry, pCurrentDentry, sizeof(RFSD_DENTRY_HEAD));				
                
                RfsdPrint(( DBG_INFO, __FUNCTION__ ": Found: Name=%S Key=%xh,%xh\n",
                            InodeFileName.Buffer, pCurrentDentry->deh_dir_id, pCurrentDentry->deh_objectid ));

				Status = STATUS_EVENT_DONE;
				break;
            }
            
		  ProcessNextEntry:
			// Advance to the next directory entry
			pPrevDentry = pCurrentDentry;
            ++idxDentryInSpan;
			++(pCallbackContext->idxCurrentDentry);
        }

        if (!bFound) {
			// Indicate success, so that parsing will continue with subsequent blocks.
            Status = STATUS_SUCCESS;
        }
	} __finally {
		if (pBlockBuffer)			ExFreePool(pBlockBuffer);
		if (InodeFileName.Buffer)	ExFreePool(InodeFileName.Buffer);
	}


	return Status;

}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -