Exemplo n.º 1
0
// We must NOT call without VCB lcok
PDokanFCB
DokanAllocateFCB(
	__in PDokanVCB Vcb
	)
{
	PDokanFCB fcb = ExAllocatePool(sizeof(DokanFCB));

	if (fcb == NULL) {
		return NULL;
	}

	ASSERT(fcb != NULL);
	ASSERT(Vcb != NULL);

	RtlZeroMemory(fcb, sizeof(DokanFCB));

	fcb->Identifier.Type = FCB;
	fcb->Identifier.Size = sizeof(DokanFCB);

	fcb->Vcb = Vcb;

	ExInitializeResourceLite(&fcb->MainResource);
	ExInitializeResourceLite(&fcb->PagingIoResource);

	ExInitializeFastMutex(&fcb->AdvancedFCBHeaderMutex);

#if _WIN32_WINNT >= 0x0501
	FsRtlSetupAdvancedHeader(&fcb->AdvancedFCBHeader, &fcb->AdvancedFCBHeaderMutex);
#else
	if (DokanFsRtlTeardownPerStreamContexts) {
		FsRtlSetupAdvancedHeader(&fcb->AdvancedFCBHeader, &fcb->AdvancedFCBHeaderMutex);
	}
#endif


	fcb->AdvancedFCBHeader.ValidDataLength.LowPart = 0xffffffff;
	fcb->AdvancedFCBHeader.ValidDataLength.HighPart = 0x7fffffff;

	fcb->AdvancedFCBHeader.Resource = &fcb->MainResource;
	fcb->AdvancedFCBHeader.PagingIoResource = &fcb->PagingIoResource;

	fcb->AdvancedFCBHeader.AllocationSize.QuadPart = 4096;
	fcb->AdvancedFCBHeader.FileSize.QuadPart = 4096;

	fcb->AdvancedFCBHeader.IsFastIoPossible = FastIoIsNotPossible;

	ExInitializeResourceLite(&fcb->Resource);

	InitializeListHead(&fcb->NextCCB);
	InsertTailList(&Vcb->NextFCB, &fcb->NextFCB);

	InterlockedIncrement(&Vcb->FcbAllocated);

	return fcb;
}
Exemplo n.º 2
0
PFCB
NTAPI
FatCreateDcb(IN PFAT_IRP_CONTEXT IrpContext,
             IN PVCB Vcb,
             IN PFCB ParentDcb,
             IN FF_FILE *FileHandle)
{
    PFCB Fcb;

    /* Allocate it and zero it */
    Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
    RtlZeroMemory(Fcb, sizeof(FCB));

    /* Set node types */
    Fcb->Header.NodeTypeCode = FAT_NTC_DCB;
    Fcb->Header.NodeByteSize = sizeof(FCB);
    Fcb->Condition = FcbGood;

    /* Initialize resources */
    Fcb->Header.Resource = &Fcb->Resource;
    ExInitializeResourceLite(Fcb->Header.Resource);

    Fcb->Header.PagingIoResource = &Fcb->PagingIoResource;
    ExInitializeResourceLite(Fcb->Header.PagingIoResource);

    /* Initialize mutexes */
    Fcb->Header.FastMutex = &Fcb->HeaderMutex;
    ExInitializeFastMutex(&Fcb->HeaderMutex);
    FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);

    /* Insert into parent's DCB list */
    InsertHeadList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks);

    /* Set backlinks */
    Fcb->ParentFcb = ParentDcb;
    Fcb->Vcb = Vcb;

    /* Initialize parent dcb list */
    InitializeListHead(&Fcb->Dcb.ParentDcbList);

    /* Set FullFAT handle */
    Fcb->FatHandle = FileHandle;

    /* Set names */
    if (FileHandle)
    {
        FatSetFcbNames(IrpContext, Fcb);

        /* Ensure the full name is set */
        FatSetFullFileNameInFcb(IrpContext, Fcb);
    }

    return Fcb;
}
Exemplo n.º 3
0
PFCB
NTAPI
FatCreateFcb(IN PFAT_IRP_CONTEXT IrpContext,
             IN PVCB Vcb,
             IN PFCB ParentDcb,
             IN FF_FILE *FileHandle)
{
    PFCB Fcb;

    /* Allocate it and zero it */
    Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(FCB), TAG_FCB);
    RtlZeroMemory(Fcb, sizeof(FCB));

    /* Set node types */
    Fcb->Header.NodeTypeCode = FAT_NTC_FCB;
    Fcb->Header.NodeByteSize = sizeof(FCB);
    Fcb->Condition = FcbGood;

    /* Initialize resources */
    Fcb->Header.Resource = &Fcb->Resource;
    ExInitializeResourceLite(Fcb->Header.Resource);

    Fcb->Header.PagingIoResource = &Fcb->PagingIoResource;
    ExInitializeResourceLite(Fcb->Header.PagingIoResource);

    /* Initialize mutexes */
    Fcb->Header.FastMutex = &Fcb->HeaderMutex;
    ExInitializeFastMutex(&Fcb->HeaderMutex);
    FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);

    /* Insert into parent's DCB list */
    InsertTailList(&ParentDcb->Dcb.ParentDcbList, &Fcb->ParentDcbLinks);

    /* Set backlinks */
    Fcb->ParentFcb = ParentDcb;
    Fcb->Vcb = Vcb;

    /* Set file handle and sizes */
    Fcb->Header.FileSize.LowPart = FileHandle->Filesize;
    Fcb->Header.ValidDataLength.LowPart = FileHandle->Filesize;
    Fcb->FatHandle = FileHandle;

    /* Initialize locks */
    FsRtlInitializeFileLock(&Fcb->Fcb.Lock, NULL, NULL);
    FsRtlInitializeOplock(&Fcb->Fcb.Oplock);

    /* Set names */
    FatSetFcbNames(IrpContext, Fcb);

    return Fcb;
}
Exemplo n.º 4
0
NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject,
    ULONG ExtraSize, FSP_FILE_NODE **PFileNode)
{
    PAGED_CODE();

    *PFileNode = 0;

    FSP_FILE_NODE_NONPAGED *NonPaged = FspAllocNonPaged(sizeof *NonPaged);
    if (0 == NonPaged)
        return STATUS_INSUFFICIENT_RESOURCES;

    FSP_FILE_NODE *FileNode = FspAlloc(sizeof *FileNode + ExtraSize);
    if (0 == FileNode)
    {
        FspFree(NonPaged);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlZeroMemory(NonPaged, sizeof *NonPaged);
    ExInitializeResourceLite(&NonPaged->Resource);
    ExInitializeResourceLite(&NonPaged->PagingIoResource);
    ExInitializeFastMutex(&NonPaged->HeaderFastMutex);
    KeInitializeSpinLock(&NonPaged->DirInfoSpinLock);

    RtlZeroMemory(FileNode, sizeof *FileNode + ExtraSize);
    FileNode->Header.NodeTypeCode = FspFileNodeFileKind;
    FileNode->Header.NodeByteSize = sizeof *FileNode;
    FileNode->Header.IsFastIoPossible = FastIoIsNotPossible;
    FileNode->Header.Resource = &NonPaged->Resource;
    FileNode->Header.PagingIoResource = &NonPaged->PagingIoResource;
    FileNode->Header.ValidDataLength.QuadPart = MAXLONGLONG;
        /* disable ValidDataLength functionality */
    FsRtlSetupAdvancedHeader(&FileNode->Header, &NonPaged->HeaderFastMutex);
    FileNode->NonPaged = NonPaged;
    FileNode->RefCount = 1;
    FileNode->FsvolDeviceObject = DeviceObject;
    FspDeviceReference(FileNode->FsvolDeviceObject);
    RtlInitEmptyUnicodeString(&FileNode->FileName, FileNode->FileNameBuf, (USHORT)ExtraSize);

    FsRtlInitializeFileLock(&FileNode->FileLock, FspFileNodeCompleteLockIrp, 0);

    *PFileNode = FileNode;

    return STATUS_SUCCESS;
}
Exemplo n.º 5
0
NTSTATUS
AFSInitRootFcb( IN ULONGLONG ProcessID,
                IN AFSVolumeCB *VolumeCB)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSFcb *pFcb = NULL;
    AFSNonPagedFcb *pNPFcb = NULL;
    IO_STATUS_BLOCK stIoStatus = {0,0};
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;

    __Enter
    {

        //
        // Initialize the root fcb
        //

        pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
                                                   sizeof( AFSFcb),
                                                   AFS_FCB_ALLOCATION_TAG);

        if( pFcb == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitRootFcb Failed to allocate the root fcb\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlZeroMemory( pFcb,
                       sizeof( AFSFcb));

        pFcb->Header.NodeByteSize = sizeof( AFSFcb);
        pFcb->Header.NodeTypeCode = AFS_ROOT_FCB;

        pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                             sizeof( AFSNonPagedFcb),
                                                             AFS_FCB_NP_ALLOCATION_TAG);

        if( pNPFcb == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitRootFcb Failed to allocate the non-paged fcb\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlZeroMemory( pNPFcb,
                       sizeof( AFSNonPagedFcb));

        pNPFcb->Size = sizeof( AFSNonPagedFcb);
        pNPFcb->Type = AFS_NON_PAGED_FCB;

        //
        // OK, initialize the entry
        //

        ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);

        FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);

        ExInitializeResourceLite( &pNPFcb->Resource);

        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSInitRootFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
                      &pNPFcb->Resource,
                      PsGetCurrentThread());

        AFSAcquireExcl( &pNPFcb->Resource,
                        TRUE);

        ExInitializeResourceLite( &pNPFcb->PagingResource);

        ExInitializeResourceLite( &pNPFcb->CcbListLock);

        pFcb->Header.Resource = &pNPFcb->Resource;

        pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;

        pFcb->NPFcb = pNPFcb;

        //
        // Initialize enumeration information
        //

        KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
                           NotificationEvent,
                           FALSE);

        //
        // Save the root Fcb in the VolumeCB
        //

        VolumeCB->ObjectInformation.Fcb = pFcb;

        VolumeCB->ObjectInformation.VolumeCB = VolumeCB;

        VolumeCB->RootFcb = pFcb;

        pFcb->ObjectInformation = &VolumeCB->ObjectInformation;

try_exit:

        if( !NT_SUCCESS( ntStatus))
        {

            if( pFcb != NULL)
            {

                AFSRemoveRootFcb( pFcb);
            }
        }
    }

    return ntStatus;
}
Exemplo n.º 6
0
NTSTATUS
AFSInitFcb( IN AFSDirectoryCB  *DirEntry,
            IN OUT AFSFcb     **Fcb)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
    AFSFcb *pFcb = NULL;
    AFSNonPagedFcb *pNPFcb = NULL;
    IO_STATUS_BLOCK stIoSb = {0,0};
    BOOLEAN bUninitFileLock = FALSE;
    USHORT  usFcbLength = 0;
    ULONGLONG   ullIndex = 0;
    AFSDirEnumEntry *pDirEnumCB = NULL;
    AFSObjectInfoCB *pObjectInfo = NULL, *pParentObjectInfo = NULL;
    AFSVolumeCB *pVolumeCB = NULL;

    __Enter
    {

        pObjectInfo = DirEntry->ObjectInformation;

        pParentObjectInfo = pObjectInfo->ParentObjectInformation;

        pVolumeCB = pObjectInfo->VolumeCB;

        //
        // Allocate the Fcb and the nonpaged portion of the Fcb.
        //

        AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE_2,
                      "AFSInitFcb Initializing fcb for %wZ FID %08lX-%08lX-%08lX-%08lX\n",
                      &DirEntry->NameInformation.FileName,
                      pObjectInfo->FileId.Cell,
                      pObjectInfo->FileId.Volume,
                      pObjectInfo->FileId.Vnode,
                      pObjectInfo->FileId.Unique);

        usFcbLength = sizeof( AFSFcb);

        pFcb = (AFSFcb *)AFSExAllocatePoolWithTag( PagedPool,
                                                   usFcbLength,
                                                   AFS_FCB_ALLOCATION_TAG);

        if( pFcb == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitFcb Failed to allocate fcb\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlZeroMemory( pFcb,
                       usFcbLength);

        pFcb->Header.NodeByteSize = usFcbLength;

        pNPFcb = (AFSNonPagedFcb *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                             sizeof( AFSNonPagedFcb),
                                                             AFS_FCB_NP_ALLOCATION_TAG);

        if( pNPFcb == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitFcb Failed to allocate non-paged fcb\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlZeroMemory( pNPFcb,
                       sizeof( AFSNonPagedFcb));

        pNPFcb->Size = sizeof( AFSNonPagedFcb);
        pNPFcb->Type = AFS_NON_PAGED_FCB;

        //
        // Initialize the advanced header
        //

        ExInitializeFastMutex( &pNPFcb->AdvancedHdrMutex);

        FsRtlSetupAdvancedHeader( &pFcb->Header, &pNPFcb->AdvancedHdrMutex);

        //
        // OK, initialize the entry
        //

        ExInitializeResourceLite( &pNPFcb->Resource);

        ExInitializeResourceLite( &pNPFcb->PagingResource);

        ExInitializeResourceLite( &pNPFcb->CcbListLock);

        pFcb->Header.Resource = &pNPFcb->Resource;

        pFcb->Header.PagingIoResource = &pNPFcb->PagingResource;

        //
        // Grab the Fcb for processing
        //

        AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSInitFcb Acquiring Fcb lock %08lX EXCL %08lX\n",
                      &pNPFcb->Resource,
                      PsGetCurrentThread());

        AFSAcquireExcl( &pNPFcb->Resource,
                        TRUE);

        pFcb->NPFcb = pNPFcb;

        //
        // Initialize some fields in the Fcb
        //

        pFcb->ObjectInformation = pObjectInfo;

        pObjectInfo->Fcb = pFcb;

        //
        // Set type specific information
        //

        if( pObjectInfo->FileType == AFS_FILE_TYPE_DIRECTORY)
        {

            //
            // Reset the type to a directory type
            //

            pFcb->Header.NodeTypeCode = AFS_DIRECTORY_FCB;

            //
            // Initialize enumeration information
            //

            KeInitializeEvent( &pFcb->NPFcb->Specific.Directory.DirectoryEnumEvent,
                               NotificationEvent,
                               FALSE);
        }
        else if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
        {

            pFcb->Header.NodeTypeCode = AFS_FILE_FCB;

            //
            // Initialize the file specific information
            //

            FsRtlInitializeFileLock( &pFcb->Specific.File.FileLock,
                                     NULL,
                                     NULL);

            bUninitFileLock = TRUE;

            //
            // Initialize the header file sizes to our dir entry information
            //

            pFcb->Header.AllocationSize.QuadPart = pObjectInfo->AllocationSize.QuadPart;
            pFcb->Header.FileSize.QuadPart = pObjectInfo->EndOfFile.QuadPart;
            pFcb->Header.ValidDataLength.QuadPart = pObjectInfo->EndOfFile.QuadPart;

            //
            // Initialize the Extents resources and so forth.  The
            // quiescent state is that no one has the extents for
            // IO (do the extents are not busy) and there is no
            // extents request outstanding (and hence the "last
            // one" is complete).
            //
            ExInitializeResourceLite( &pNPFcb->Specific.File.ExtentsResource );

            KeInitializeEvent( &pNPFcb->Specific.File.ExtentsRequestComplete,
                               NotificationEvent,
                               TRUE );

            for (ULONG i = 0; i < AFS_NUM_EXTENT_LISTS; i++)
            {
                InitializeListHead(&pFcb->Specific.File.ExtentsLists[i]);
            }

            pNPFcb->Specific.File.DirtyListHead = NULL;
            pNPFcb->Specific.File.DirtyListTail = NULL;

            ExInitializeResourceLite( &pNPFcb->Specific.File.DirtyExtentsListLock);

            KeInitializeEvent( &pNPFcb->Specific.File.FlushEvent,
                               SynchronizationEvent,
                               TRUE);

            KeInitializeEvent( &pNPFcb->Specific.File.QueuedFlushEvent,
                               NotificationEvent,
                               TRUE);
        }
        else if( pObjectInfo->FileType == AFS_FILE_TYPE_SPECIAL_SHARE_NAME)
        {

            pFcb->Header.NodeTypeCode = AFS_SPECIAL_SHARE_FCB;
        }
        else if( pObjectInfo->FileType == AFS_FILE_TYPE_PIOCTL)
        {

            pFcb->Header.NodeTypeCode = AFS_IOCTL_FCB;
        }
        else if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK)
        {

            pFcb->Header.NodeTypeCode = AFS_SYMBOLIC_LINK_FCB;
        }
        else if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
        {

            pFcb->Header.NodeTypeCode = AFS_MOUNT_POINT_FCB;
        }
        else if( pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
        {
            pFcb->Header.NodeTypeCode = AFS_DFS_LINK_FCB;
        }
        else
        {
            pFcb->Header.NodeTypeCode = AFS_INVALID_FCB;
        }

        //
        // And return the Fcb
        //

        *Fcb = pFcb;

        AFSDbgLogMsg( AFS_SUBSYSTEM_FCB_REF_COUNTING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "AFSInitFcb Initialized Fcb %08lX Name %wZ\n",
                      pFcb,
                      &DirEntry->NameInformation.FileName);

try_exit:

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSInitFcb Failed to initialize fcb Status %08lX\n",
                          ntStatus);

            if( pFcb != NULL)
            {

                if( bUninitFileLock)
                {

                    FsRtlUninitializeFileLock( &pFcb->Specific.File.FileLock);
                }

                if( pNPFcb != NULL)
                {

                    AFSReleaseResource( &pNPFcb->Resource);

                    ExDeleteResourceLite( &pNPFcb->PagingResource);

                    ExDeleteResourceLite( &pNPFcb->CcbListLock);

                    ExDeleteResourceLite( &pNPFcb->Resource);
                }

                AFSExFreePool( pFcb);
            }

            if( pNPFcb != NULL)
            {

                AFSExFreePool( pNPFcb);
            }

            if( Fcb != NULL)
            {

                *Fcb = NULL;
            }
        }
    }

    return ntStatus;
}
Exemplo n.º 7
0
NTSTATUS
DokanCreateDiskDevice(__in PDRIVER_OBJECT DriverObject, __in ULONG MountId,
                      __in PWCHAR MountPoint, __in PWCHAR UNCName,
                      __in PWCHAR BaseGuid, __in PDOKAN_GLOBAL DokanGlobal,
                      __in DEVICE_TYPE DeviceType,
                      __in ULONG DeviceCharacteristics,
                      __in BOOLEAN UseMountManager, __out PDokanDCB *Dcb) {
  WCHAR diskDeviceNameBuf[MAXIMUM_FILENAME_LENGTH];
  WCHAR symbolicLinkNameBuf[MAXIMUM_FILENAME_LENGTH];
  WCHAR mountPointBuf[MAXIMUM_FILENAME_LENGTH];
  PDEVICE_OBJECT diskDeviceObject;
  PDEVICE_OBJECT volDeviceObject;
  PDokanDCB dcb;
  PDokanVCB vcb;
  UNICODE_STRING diskDeviceName;
  NTSTATUS status;
  BOOLEAN isNetworkFileSystem = (DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM);
  DOKAN_CONTROL dokanControl;

  // make DeviceName and SymboliLink
  if (isNetworkFileSystem) {
#ifdef DOKAN_NET_PROVIDER
    RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH,
                      DOKAN_NET_DEVICE_NAME);
    RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH,
                      DOKAN_NET_SYMBOLIC_LINK_NAME);
#else
    RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH,
                      DOKAN_NET_DEVICE_NAME);
    RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
    RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH,
                      DOKAN_NET_SYMBOLIC_LINK_NAME);
    RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
#endif

  } else {
    RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH,
                      DOKAN_DISK_DEVICE_NAME);
    RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
    RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH,
                      DOKAN_SYMBOLIC_LINK_NAME);
    RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
  }

  RtlInitUnicodeString(&diskDeviceName, diskDeviceNameBuf);

  //
  // Create DeviceObject for the Disk Device
  //
  if (!isNetworkFileSystem) {
    status =
        IoCreateDeviceSecure(DriverObject,          // DriverObject
                             sizeof(DokanDCB),      // DeviceExtensionSize
                             &diskDeviceName,       // DeviceName
                             FILE_DEVICE_DISK,      // DeviceType
                             DeviceCharacteristics, // DeviceCharacteristics
                             FALSE,                 // Not Exclusive
                             &sddl,                 // Default SDDL String
                             NULL,                  // Device Class GUID
                             &diskDeviceObject);    // DeviceObject
  } else {
    status = IoCreateDevice(DriverObject,          // DriverObject
                            sizeof(DokanDCB),      // DeviceExtensionSize
                            NULL,                  // DeviceName
                            FILE_DEVICE_UNKNOWN,   // DeviceType
                            DeviceCharacteristics, // DeviceCharacteristics
                            FALSE,                 // Not Exclusive
                            &diskDeviceObject);    // DeviceObject
  }

  if (!NT_SUCCESS(status)) {
    DDbgPrint("  %s failed: 0x%x\n",
              isNetworkFileSystem ? "IoCreateDevice(FILE_DEVICE_UNKNOWN)"
                                  : "IoCreateDeviceSecure(FILE_DEVICE_DISK)",
              status);
    return status;
  }

  //
  // Initialize the device extension.
  //
  dcb = diskDeviceObject->DeviceExtension;
  *Dcb = dcb;
  dcb->DeviceObject = diskDeviceObject;
  dcb->Global = DokanGlobal;

  dcb->Identifier.Type = DCB;
  dcb->Identifier.Size = sizeof(DokanDCB);

  dcb->MountId = MountId;
  dcb->DeviceType = FILE_DEVICE_DISK;
  dcb->DeviceCharacteristics = DeviceCharacteristics;
  KeInitializeEvent(&dcb->KillEvent, NotificationEvent, FALSE);

  //
  // Establish user-buffer access method.
  //
  diskDeviceObject->Flags |= DO_DIRECT_IO;

  // initialize Event and Event queue
  DokanInitIrpList(&dcb->PendingIrp);
  DokanInitIrpList(&dcb->PendingEvent);
  DokanInitIrpList(&dcb->NotifyEvent);

  KeInitializeEvent(&dcb->ReleaseEvent, NotificationEvent, FALSE);

  // "0" means not mounted
  dcb->Mounted = 0;

  ExInitializeResourceLite(&dcb->Resource);

  dcb->CacheManagerNoOpCallbacks.AcquireForLazyWrite = &DokanNoOpAcquire;
  dcb->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &DokanNoOpRelease;
  dcb->CacheManagerNoOpCallbacks.AcquireForReadAhead = &DokanNoOpAcquire;
  dcb->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &DokanNoOpRelease;

  dcb->UseMountManager = UseMountManager;
  if (wcscmp(MountPoint, L"") != 0) {
    RtlStringCchCopyW(mountPointBuf, MAXIMUM_FILENAME_LENGTH,
                      L"\\DosDevices\\");
    if (wcslen(MountPoint) < 4) {
      mountPointBuf[12] = towupper(MountPoint[0]);
      mountPointBuf[13] = L':';
      mountPointBuf[14] = L'\0';
      if (isNetworkFileSystem) {
        dcb->UseMountManager = FALSE;
      }
    } else {
      dcb->UseMountManager = FALSE;
      RtlStringCchCatW(mountPointBuf, MAXIMUM_FILENAME_LENGTH, MountPoint);
    }
  } else {
    RtlStringCchCopyW(mountPointBuf, MAXIMUM_FILENAME_LENGTH, L"");
  }

  dcb->DiskDeviceName = DokanAllocateUnicodeString(diskDeviceNameBuf);
  dcb->SymbolicLinkName = DokanAllocateUnicodeString(symbolicLinkNameBuf);
  dcb->MountPoint = DokanAllocateUnicodeString(mountPointBuf);
  if (UNCName != NULL) {
    dcb->UNCName = DokanAllocateUnicodeString(UNCName);
  }

  if (dcb->DiskDeviceName == NULL || dcb->SymbolicLinkName == NULL ||
      dcb->MountPoint == NULL || (dcb->UNCName == NULL && UNCName != NULL)) {
    DDbgPrint("  Failed to allocate memory for device naming");
    FreeDcbNames(dcb);
    ExDeleteResourceLite(&dcb->Resource);
    IoDeleteDevice(diskDeviceObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }
  DDbgPrint("DiskDeviceName: %wZ - SymbolicLinkName: %wZ - MountPoint: %wZ\n",
            dcb->DiskDeviceName, dcb->SymbolicLinkName, dcb->MountPoint);

  DDbgPrint("  IoCreateDevice DeviceType: %d\n", DeviceType);

  // Directly create volume device and init vcb here because it has strong
  // dependency with fs/disk
  // Otherwise we would have done this work when mounting the volume

  if (!isNetworkFileSystem) {
    status = IoCreateDevice(DriverObject,          // DriverObject
                            sizeof(DokanVCB),      // DeviceExtensionSize
                            NULL,                  // DeviceName
                            DeviceType,            // DeviceType
                            DeviceCharacteristics, // DeviceCharacteristics
                            FALSE,                 // Not Exclusive
                            &volDeviceObject);     // DeviceObject
  } else {
    status =
        IoCreateDeviceSecure(DriverObject,          // DriverObject
                             sizeof(DokanVCB),      // DeviceExtensionSize
                             &diskDeviceName,       // DeviceName
                             DeviceType,            // DeviceType
                             DeviceCharacteristics, // DeviceCharacteristics
                             FALSE,                 // Not Exclusive
                             &sddl,                 // Default SDDL String
                             NULL,                  // Device Class GUID
                             &volDeviceObject);     // DeviceObject
  }

  if (!NT_SUCCESS(status)) {
    DDbgPrint("  IoCreateDevice failed: 0x%x\n", status);
    ExDeleteResourceLite(&dcb->Resource);
    IoDeleteDevice(diskDeviceObject);
    FreeDcbNames(dcb);
    return status;
  }

  vcb = volDeviceObject->DeviceExtension;
  vcb->Identifier.Type = VCB;
  vcb->Identifier.Size = sizeof(DokanVCB);

  vcb->DeviceObject = volDeviceObject;
  vcb->Dcb = dcb;
  dcb->Vcb = vcb;

  InitializeListHead(&vcb->NextFCB);

  InitializeListHead(&vcb->DirNotifyList);
  FsRtlNotifyInitializeSync(&vcb->NotifySync);

  ExInitializeFastMutex(&vcb->AdvancedFCBHeaderMutex);

#if _WIN32_WINNT >= 0x0501
  FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader,
                           &vcb->AdvancedFCBHeaderMutex);
#else
  if (DokanFsRtlTeardownPerStreamContexts) {
    FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader,
                             &vcb->AdvancedFCBHeaderMutex);
  }
#endif

  //
  // Create a symbolic link for userapp to interact with the driver.
  //
  status = IoCreateSymbolicLink(dcb->SymbolicLinkName, dcb->DiskDeviceName);

  if (!NT_SUCCESS(status)) {
    ExDeleteResourceLite(&dcb->Resource);
    IoDeleteDevice(diskDeviceObject);
    FreeDcbNames(dcb);
    DDbgPrint("  IoCreateSymbolicLink returned 0x%x\n", status);
    return status;
  }
  DDbgPrint("SymbolicLink: %wZ -> %wZ created\n", dcb->SymbolicLinkName,
            dcb->DiskDeviceName);

  //
  // Establish user-buffer access method.
  //
  volDeviceObject->Flags |= DO_DIRECT_IO;

  DokanInitVpb(diskDeviceObject->Vpb, diskDeviceObject, volDeviceObject);

  // Mark devices as initialized
  diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  volDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

  ObReferenceObject(volDeviceObject);
  ObReferenceObject(diskDeviceObject);

  // DokanRegisterMountedDeviceInterface(diskDeviceObject, dcb);

  // Save to the global mounted list
  RtlZeroMemory(&dokanControl, sizeof(dokanControl));
  RtlStringCchCopyW(dokanControl.DeviceName,
                    sizeof(dokanControl.DeviceName) / sizeof(WCHAR),
                    diskDeviceNameBuf);
  RtlStringCchCopyW(dokanControl.MountPoint,
                    sizeof(dokanControl.MountPoint) / sizeof(WCHAR),
                    mountPointBuf);
  dokanControl.Type = DeviceType;
  dokanControl.DeviceObject = volDeviceObject;
  InsertMountEntry(DokanGlobal, &dokanControl);

  dcb->Mounted = 1;

  if (dcb->UseMountManager) {
    status = DokanSendVolumeArrivalNotification(dcb->DiskDeviceName);
    if (!NT_SUCCESS(status)) {
      DDbgPrint("  DokanSendVolumeArrivalNotification failed: 0x%x\n", status);
      if (diskDeviceObject->Vpb) {
        diskDeviceObject->Vpb->DeviceObject = NULL;
        diskDeviceObject->Vpb->RealDevice = NULL;
        diskDeviceObject->Vpb->Flags = 0;
      }
      ExDeleteResourceLite(&dcb->Resource);
      IoDeleteDevice(diskDeviceObject);
      FreeDcbNames(dcb);
      return status;
    }
  }

  DokanCreateMountPoint(dcb);

  if (isNetworkFileSystem) {
    // Run FsRtlRegisterUncProvider in System thread.
    HANDLE handle;
    PKTHREAD thread;
    OBJECT_ATTRIBUTES objectAttribs;

    InitializeObjectAttributes(&objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL,
                               NULL);
    status = PsCreateSystemThread(
        &handle, THREAD_ALL_ACCESS, &objectAttribs, NULL, NULL,
        (PKSTART_ROUTINE)DokanRegisterUncProvider, dcb);
    if (!NT_SUCCESS(status)) {
      DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status);
    } else {
      ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL, KernelMode,
                                &thread, NULL);
      ZwClose(handle);
      KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
      ObDereferenceObject(thread);
    }
  }
  // DokanRegisterDeviceInterface(DriverObject, diskDeviceObject, dcb);

  return STATUS_SUCCESS;
}
Exemplo n.º 8
0
PNDAS_FCB
ReadonlyAllocateFcb (
	IN PFILESPY_DEVICE_EXTENSION	DevExt,
	IN PUNICODE_STRING				FullFileName,
	IN BOOLEAN						IsPagingFile
    )
{
    PNDAS_FCB fcb;

	
    fcb = FsRtlAllocatePoolWithTag( NonPagedPool,
									sizeof(NDAS_FCB),
									LFS_FCB_TAG );
	
	if (fcb == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb\n") );
		return NULL;
	}
	
	RtlZeroMemory( fcb, sizeof(NDAS_FCB) );

    fcb->NonPaged = LfsAllocateNonPagedFcb();
	
	if (fcb->NonPaged == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->NonPaged\n") );
		ExFreePool( fcb );
		
		return NULL;
	}

    RtlZeroMemory( fcb->NonPaged, sizeof(NON_PAGED_FCB) );

#define FAT_NTC_FCB                      (0x0502)
	
	fcb->Header.NodeTypeCode = FAT_NTC_FCB;
	fcb->Header.IsFastIoPossible = FastIoIsPossible;
    fcb->Header.Resource = LfsAllocateResource();
	fcb->Header.PagingIoResource = NULL; //fcb->Header.Resource;
	
	if (fcb->Header.Resource == NULL) {
	
		SPY_LOG_PRINT( LFS_DEBUG_READONLY_ERROR, ("ReadonlyAllocateFcb: failed to allocate fcb->Header.Resource\n") );
		ExFreePool( fcb->NonPaged );
		ExFreePool( fcb );
		return NULL;
	}

	if (LfsFsRtlTeardownPerStreamContexts) {

		ExInitializeFastMutex( &fcb->NonPaged->AdvancedFcbHeaderMutex );
		FsRtlSetupAdvancedHeader( &fcb->Header, &fcb->NonPaged->AdvancedFcbHeaderMutex );

		if (IsPagingFile) {

			ClearFlag( fcb->Header.Flags2, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS );
		}
	}

	FsRtlInitializeFileLock( &fcb->FileLock, NULL, NULL );

	fcb->ReferenceCount = 1;
	InitializeListHead( &fcb->ListEntry );

	fcb->Readonly = DevExt->LfsDeviceExt.Readonly;

    RtlInitEmptyUnicodeString( &fcb->FullFileName,
							   fcb->FullFileNameBuffer,
							   sizeof(fcb->FullFileNameBuffer) );

	RtlCopyUnicodeString( &fcb->FullFileName, FullFileName );

    RtlInitEmptyUnicodeString( &fcb->CaseInSensitiveFullFileName,
							   fcb->CaseInSensitiveFullFileNameBuffer,
							   sizeof(fcb->CaseInSensitiveFullFileNameBuffer) );

	RtlDowncaseUnicodeString( &fcb->CaseInSensitiveFullFileName,
							  &fcb->FullFileName,
							  FALSE );

	if(FullFileName->Length)
		if(FullFileName->Buffer[0] != L'\\')
			ASSERT( LFS_BUG );
	
	return fcb;
}
Exemplo n.º 9
0
static
NTSTATUS
TestIrpHandler(
    _In_ PDEVICE_OBJECT DeviceObject,
    _In_ PIRP Irp,
    _In_ PIO_STACK_LOCATION IoStack)
{
    NTSTATUS Status;
    PTEST_FCB Fcb;
    CACHE_UNINITIALIZE_EVENT CacheUninitEvent;

    PAGED_CODE();

    DPRINT("IRP %x/%x\n", IoStack->MajorFunction, IoStack->MinorFunction);
    ASSERT(IoStack->MajorFunction == IRP_MJ_CLEANUP ||
           IoStack->MajorFunction == IRP_MJ_CREATE ||
           IoStack->MajorFunction == IRP_MJ_READ);

    Status = STATUS_NOT_SUPPORTED;
    Irp->IoStatus.Information = 0;

    if (IoStack->MajorFunction == IRP_MJ_CREATE)
    {
        if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR))
        {
            TestDeviceObject = DeviceObject;
            TestFileObject = IoStack->FileObject;
        }
        Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Fcb), 'FwrI');
        RtlZeroMemory(Fcb, sizeof(*Fcb));
        ExInitializeFastMutex(&Fcb->HeaderMutex);
        FsRtlSetupAdvancedHeader(&Fcb->Header, &Fcb->HeaderMutex);
        if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
            IoStack->FileObject->FileName.Buffer[1] == 'B')
        {
            Fcb->Header.AllocationSize.QuadPart = 1000000;
            Fcb->Header.FileSize.QuadPart = 1000000;
            Fcb->Header.ValidDataLength.QuadPart = 1000000;
        }
        else if (IoStack->FileObject->FileName.Length >= 2 * sizeof(WCHAR) &&
                 IoStack->FileObject->FileName.Buffer[1] == 'S')
        {
            Fcb->Header.AllocationSize.QuadPart = 3000;
            Fcb->Header.FileSize.QuadPart = 3000;
            Fcb->Header.ValidDataLength.QuadPart = 3000;
        }
        else
        {
            Fcb->Header.AllocationSize.QuadPart = 512;
            Fcb->Header.FileSize.QuadPart = 512;
            Fcb->Header.ValidDataLength.QuadPart = 512;
        }
        Fcb->Header.IsFastIoPossible = FALSE;
        IoStack->FileObject->FsContext = Fcb;
        IoStack->FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;

        CcInitializeCacheMap(IoStack->FileObject, 
                             (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
                             FALSE, &Callbacks, NULL);

        Irp->IoStatus.Information = FILE_OPENED;
        Status = STATUS_SUCCESS;
    }
    else if (IoStack->MajorFunction == IRP_MJ_READ)
    {
        BOOLEAN Ret;
        ULONG Length;
        PVOID Buffer;
        LARGE_INTEGER Offset;

        Offset = IoStack->Parameters.Read.ByteOffset;
        Length = IoStack->Parameters.Read.Length;
        Fcb = IoStack->FileObject->FsContext;

        ok_eq_pointer(DeviceObject, TestDeviceObject);
        ok_eq_pointer(IoStack->FileObject, TestFileObject);

        if (!FlagOn(Irp->Flags, IRP_NOCACHE))
        {
            ok(Offset.QuadPart % 512 != 0, "Offset is aligned: %I64i\n", Offset.QuadPart);
            ok(Length % 512 != 0, "Length is aligned: %I64i\n", Length);

            Buffer = MapUserBuffer(Irp);
            ok(Buffer != NULL, "Null pointer!\n");

            _SEH2_TRY
            {
                Ret = CcCopyRead(IoStack->FileObject, &Offset, Length, TRUE, Buffer,
                                 &Irp->IoStatus);
                ok_bool_true(Ret, "CcCopyRead");
            }
            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
            {
                Irp->IoStatus.Status = _SEH2_GetExceptionCode();
            }
            _SEH2_END;

            Status = Irp->IoStatus.Status;
        }
Exemplo n.º 10
0
VOID
NTAPI
FatCreateRootDcb(IN PFAT_IRP_CONTEXT IrpContext,
                 IN PVCB Vcb)
{
    PFCB Dcb;

    /* Make sure it's not already created */
    ASSERT(!Vcb->RootDcb);

    /* Allocate the DCB */
    Dcb = FsRtlAllocatePoolWithTag(NonPagedPool,
                                   sizeof(FCB),
                                   TAG_FCB);

    /* Zero it */
    RtlZeroMemory(Dcb, sizeof(FCB));

    /* Assign it to the VCB */
    Vcb->RootDcb = Dcb;

    /* Set its header */
    Dcb->Header.NodeTypeCode = FAT_NTC_ROOT_DCB;
    Dcb->Header.NodeByteSize = sizeof(FCB);

    /* FCB is in a good condition */
    Dcb->Condition = FcbGood;

    /* Initialize FCB's resource */
    Dcb->Header.Resource = &Dcb->Resource;
    ExInitializeResourceLite(&Dcb->Resource);

    /* Initialize Paging Io resource*/
    Dcb->Header.PagingIoResource = &Dcb->PagingIoResource;
    ExInitializeResourceLite(&Dcb->PagingIoResource);

    /* Initialize a list of parent DCBs*/
    InitializeListHead(&Dcb->ParentDcbLinks);

    /* Set VCB */
    Dcb->Vcb = Vcb;

    /* Initialize parent's DCB list */
    InitializeListHead(&Dcb->Dcb.ParentDcbList);

    /* Initialize the full file name */
    Dcb->FullFileName.Buffer = L"\\";
    Dcb->FullFileName.Length = 1 * sizeof(WCHAR);
    Dcb->FullFileName.MaximumLength = 2 * sizeof(WCHAR);

    Dcb->ShortName.Name.Ansi.Buffer = "\\";
    Dcb->ShortName.Name.Ansi.Length = 1;
    Dcb->ShortName.Name.Ansi.MaximumLength = 2 * sizeof(CHAR);

    /* Fill dirent attribute byte copy */
    Dcb->DirentFatFlags = FILE_ATTRIBUTE_DIRECTORY;

    /* Initialize advanced FCB header fields */
    ExInitializeFastMutex(&Dcb->HeaderMutex);
    FsRtlSetupAdvancedHeader(&Dcb->Header, &Dcb->HeaderMutex);

    /* Set up first cluster field depending on FAT type */
    if (TRUE/*FatIsFat32(Vcb)*/)
    {
        /* First cluster is really the first cluster of this volume */
        Dcb->FirstClusterOfFile = Vcb->Bpb.RootDirFirstCluster;

        /* Calculate size of FAT32 root dir */
        Dcb->Header.AllocationSize.LowPart = 0xFFFFFFFF;
        //FatLookupFileAllocationSize(IrpContext, Dcb);
        DPRINT1("Calculation of a size of a root dir is missing!\n");

        Dcb->Header.FileSize.QuadPart = Dcb->Header.AllocationSize.QuadPart;
    }
    else
    {
#if 0
        /* Add MCB entry */
        FatAddMcbEntry(Vcb,
                       &Dcb->Mcb,
                       0,
                       FatRootDirectoryLbo(&Vcb->Bpb),
                       FatRootDirectorySize(&Vcb->Bpb));

        /* Set a real size of the root directory */
        Dcb->Header.FileSize.QuadPart = FatRootDirectorySize(&Vcb->Bpb);
        Dcb->Header.AllocationSize.QuadPart = Dcb->Header.FileSize.QuadPart;
#endif
        UNIMPLEMENTED;
    }
}
Exemplo n.º 11
0
NTSTATUS
DokanCreateDiskDevice(
	__in PDRIVER_OBJECT DriverObject,
	__in ULONG			MountId,
	__in PWCHAR			BaseGuid,
	__in PDOKAN_GLOBAL	DokanGlobal,
	__in DEVICE_TYPE	DeviceType,
	__in ULONG			DeviceCharacteristics,
	__out PDokanDCB*	Dcb
	)
{
	WCHAR				diskDeviceNameBuf[MAXIMUM_FILENAME_LENGTH];
	WCHAR				fsDeviceNameBuf[MAXIMUM_FILENAME_LENGTH];
	WCHAR				symbolicLinkNameBuf[MAXIMUM_FILENAME_LENGTH];
	PDEVICE_OBJECT		diskDeviceObject;
	PDEVICE_OBJECT		fsDeviceObject;
	PDokanDCB			dcb;
	PDokanVCB			vcb;
	UNICODE_STRING		diskDeviceName;
	NTSTATUS			status;
	BOOLEAN				isNetworkFileSystem = (DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM);

	// make DeviceName and SymboliLink
	if (isNetworkFileSystem) {
#ifdef DOKAN_NET_PROVIDER
		RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME);
#else
		RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME);
		RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
#endif

	} else {
		RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_DISK_DEVICE_NAME);
		RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_FS_DEVICE_NAME);
		RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_SYMBOLIC_LINK_NAME);
		RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
	}
	
	RtlInitUnicodeString(&diskDeviceName, diskDeviceNameBuf);

	//
	// make a DeviceObject for Disk Device
	//
	if (!isNetworkFileSystem) {
		status = IoCreateDeviceSecure(
					DriverObject,		// DriverObject
					sizeof(DokanDCB),	// DeviceExtensionSize
					&diskDeviceName,	// DeviceName
					FILE_DEVICE_DISK,	// DeviceType
					DeviceCharacteristics,	// DeviceCharacteristics
					FALSE,				// Not Exclusive
					&sddl, // Default SDDL String
					NULL,				// Device Class GUID
					&diskDeviceObject); // DeviceObject
	} else {
		status = IoCreateDevice(
					DriverObject,			// DriverObject
					sizeof(DokanDCB),		// DeviceExtensionSize
					NULL,					// DeviceName
					FILE_DEVICE_UNKNOWN,	// DeviceType
					DeviceCharacteristics,	// DeviceCharacteristics
					FALSE,					// Not Exclusive
					&diskDeviceObject);		// DeviceObject
	}


	if (!NT_SUCCESS(status)) {
		DDbgPrint("  IoCreateDevice (DISK_DEVICE) failed: 0x%x\n", status);
		return status;
	}
	DDbgPrint("DokanDiskDevice: %wZ created\n", &diskDeviceName);

	//
	// Initialize the device extension.
	//
	dcb = diskDeviceObject->DeviceExtension;
	*Dcb = dcb;
	dcb->DeviceObject = diskDeviceObject;
	dcb->Global = DokanGlobal;

	dcb->Identifier.Type = DCB;
	dcb->Identifier.Size = sizeof(DokanDCB);

	dcb->MountId = MountId;
	dcb->DeviceType = FILE_DEVICE_DISK;
	dcb->DeviceCharacteristics = DeviceCharacteristics;
	KeInitializeEvent(&dcb->KillEvent, NotificationEvent, FALSE);

	//
	// Establish user-buffer access method.
	//
	diskDeviceObject->Flags |= DO_DIRECT_IO;

	// initialize Event and Event queue
	DokanInitIrpList(&dcb->PendingIrp);
	DokanInitIrpList(&dcb->PendingEvent);
	DokanInitIrpList(&dcb->NotifyEvent);

	KeInitializeEvent(&dcb->ReleaseEvent, NotificationEvent, FALSE);

	// "0" means not mounted
	dcb->Mounted = 0;

	ExInitializeResourceLite(&dcb->Resource);

	dcb->CacheManagerNoOpCallbacks.AcquireForLazyWrite  = &DokanNoOpAcquire;
	dcb->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &DokanNoOpRelease;
	dcb->CacheManagerNoOpCallbacks.AcquireForReadAhead  = &DokanNoOpAcquire;
	dcb->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &DokanNoOpRelease;

	dcb->SymbolicLinkName = AllocateUnicodeString(symbolicLinkNameBuf);
	dcb->DiskDeviceName =  AllocateUnicodeString(diskDeviceNameBuf);
	dcb->FileSystemDeviceName = AllocateUnicodeString(fsDeviceNameBuf);

	status = IoCreateDeviceSecure(
				DriverObject,		// DriverObject
				sizeof(DokanVCB),	// DeviceExtensionSize
				dcb->FileSystemDeviceName, // DeviceName
				DeviceType,			// DeviceType
				DeviceCharacteristics,	// DeviceCharacteristics
				FALSE,				// Not Exclusive
				&sddl, // Default SDDL String
				NULL,				// Device Class GUID
				&fsDeviceObject);	// DeviceObject

	if (!NT_SUCCESS(status)) {
		DDbgPrint("  IoCreateDevice (FILE_SYSTEM_DEVICE) failed: 0x%x\n", status);
		IoDeleteDevice(diskDeviceObject);
		return status;
	}
	DDbgPrint("DokanFileSystemDevice: %wZ created\n", dcb->FileSystemDeviceName);

	vcb = fsDeviceObject->DeviceExtension;

	vcb->Identifier.Type = VCB;
	vcb->Identifier.Size = sizeof(DokanVCB);

	vcb->DeviceObject = fsDeviceObject;
	vcb->Dcb = dcb;

	dcb->Vcb = vcb;
	
	InitializeListHead(&vcb->NextFCB);

	InitializeListHead(&vcb->DirNotifyList);
	FsRtlNotifyInitializeSync(&vcb->NotifySync);

	ExInitializeFastMutex(&vcb->AdvancedFCBHeaderMutex);
#if _WIN32_WINNT >= 0x0501
	FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex);
#else
	if (DokanFsRtlTeardownPerStreamContexts) {
		FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex);
	}
#endif


	//
	// Establish user-buffer access method.
	//
	fsDeviceObject->Flags |= DO_DIRECT_IO;

	if (diskDeviceObject->Vpb) {
		// NOTE: This can be done by IoRegisterFileSystem + IRP_MN_MOUNT_VOLUME,
		// however that causes BSOD inside filter manager on Vista x86 after mount
		// (mouse hover on file).
		// Probably FS_FILTER_CALLBACKS.PreAcquireForSectionSynchronization is
		// not correctly called in that case.
		diskDeviceObject->Vpb->DeviceObject = fsDeviceObject;
		diskDeviceObject->Vpb->RealDevice = fsDeviceObject;
		diskDeviceObject->Vpb->Flags |= VPB_MOUNTED;
		diskDeviceObject->Vpb->VolumeLabelLength = (USHORT)wcslen(VOLUME_LABEL) * sizeof(WCHAR);
		RtlStringCchCopyW(diskDeviceObject->Vpb->VolumeLabel,
						sizeof(diskDeviceObject->Vpb->VolumeLabel) / sizeof(WCHAR),
						VOLUME_LABEL);
		diskDeviceObject->Vpb->SerialNumber = 0x19831116;
	}

	ObReferenceObject(fsDeviceObject);
	ObReferenceObject(diskDeviceObject);

	//
	// Create a symbolic link for userapp to interact with the driver.
	//
	status = IoCreateSymbolicLink(dcb->SymbolicLinkName, dcb->DiskDeviceName);

	if (!NT_SUCCESS(status)) {
		if (diskDeviceObject->Vpb) {
			diskDeviceObject->Vpb->DeviceObject = NULL;
			diskDeviceObject->Vpb->RealDevice = NULL;
			diskDeviceObject->Vpb->Flags = 0;
		}
		IoDeleteDevice(diskDeviceObject);
		IoDeleteDevice(fsDeviceObject);
		DDbgPrint("  IoCreateSymbolicLink returned 0x%x\n", status);
		return status;
	}
	DDbgPrint("SymbolicLink: %wZ -> %wZ created\n", dcb->SymbolicLinkName, dcb->DiskDeviceName);

	// Mark devices as initialized
	diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	fsDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

	//IoRegisterFileSystem(fsDeviceObject);

	if (isNetworkFileSystem) {
		// Run FsRtlRegisterUncProvider in System thread.
		HANDLE handle;
		PKTHREAD thread;
		OBJECT_ATTRIBUTES objectAttribs;

		InitializeObjectAttributes(
			&objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
		status = PsCreateSystemThread(&handle, THREAD_ALL_ACCESS,
			&objectAttribs, NULL, NULL, (PKSTART_ROUTINE)DokanRegisterUncProvider, dcb);
		if (!NT_SUCCESS(status)) {
			DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status);
		} else {
			ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL,
					KernelMode, &thread, NULL);
			ZwClose(handle);
			KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
			ObDereferenceObject(thread);
		}
	}

	//DokanRegisterMountedDeviceInterface(diskDeviceObject, dcb);
	
	dcb->Mounted = 1;

	//DokanSendVolumeArrivalNotification(&deviceName);
	//DokanRegisterDeviceInterface(DriverObject, diskDeviceObject, dcb);

	return STATUS_SUCCESS;
}