ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

static NTSTATUS FsdSetFsLabelInformation ( PDEVICE_OBJECT  DeviceObject,
PFILE_FS_LABEL_INFORMATION  FsLabelInfo 
) [static]

Definition at line 160 of file volume.c.

Referenced by VfatSetVolumeInformation().

{
  PDEVICE_EXTENSION DeviceExt;
  PVOID Context = NULL;
  ULONG DirIndex = 0;
  PDIR_ENTRY Entry;
  PVFATFCB pRootFcb;
  LARGE_INTEGER FileOffset;
  BOOLEAN LabelFound = FALSE;
  DIR_ENTRY VolumeLabelDirEntry;
  ULONG VolumeLabelDirIndex;
  ULONG LabelLen;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  OEM_STRING StringO;
  UNICODE_STRING StringW;
  CHAR cString[43];
  ULONG SizeDirEntry;
  ULONG EntriesPerPage;

  DPRINT("FsdSetFsLabelInformation()\n");

  DeviceExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

  if (sizeof(DeviceObject->Vpb->VolumeLabel) < FsLabelInfo->VolumeLabelLength)
  {
    return STATUS_NAME_TOO_LONG;
  }

  if (DeviceExt->Flags & VCB_IS_FATX)
  {
    if (FsLabelInfo->VolumeLabelLength / sizeof(WCHAR) > 42)
      return STATUS_NAME_TOO_LONG;
    SizeDirEntry = sizeof(FATX_DIR_ENTRY);
    EntriesPerPage = FATX_ENTRIES_PER_PAGE;
  }
  else
  {
    if (FsLabelInfo->VolumeLabelLength / sizeof(WCHAR) > 11)
      return STATUS_NAME_TOO_LONG;
    SizeDirEntry = sizeof(FAT_DIR_ENTRY);
    EntriesPerPage = FAT_ENTRIES_PER_PAGE;
  }

  /* Create Volume label dir entry */
  LabelLen = FsLabelInfo->VolumeLabelLength / sizeof(WCHAR);
  RtlZeroMemory(&VolumeLabelDirEntry, SizeDirEntry);
  StringW.Buffer = FsLabelInfo->VolumeLabel;
  StringW.Length = StringW.MaximumLength = (USHORT)FsLabelInfo->VolumeLabelLength;
  StringO.Buffer = cString;
  StringO.Length = 0;
  StringO.MaximumLength = 42;
  Status = RtlUnicodeStringToOemString(&StringO, &StringW, FALSE);
  if (!NT_SUCCESS(Status))
    return Status;
  if (DeviceExt->Flags & VCB_IS_FATX)
  {
    RtlCopyMemory(VolumeLabelDirEntry.FatX.Filename, cString, LabelLen);
    memset(&VolumeLabelDirEntry.FatX.Filename[LabelLen], ' ', 42 - LabelLen);
    VolumeLabelDirEntry.FatX.Attrib = _A_VOLID;
  }
  else
  {
    RtlCopyMemory(VolumeLabelDirEntry.Fat.Filename, cString, max(sizeof(VolumeLabelDirEntry.Fat.Filename), LabelLen));
    if (LabelLen > sizeof(VolumeLabelDirEntry.Fat.Filename))
    {
      memset(VolumeLabelDirEntry.Fat.Ext, ' ', sizeof(VolumeLabelDirEntry.Fat.Ext));
      RtlCopyMemory(VolumeLabelDirEntry.Fat.Ext, cString + sizeof(VolumeLabelDirEntry.Fat.Filename), LabelLen - sizeof(VolumeLabelDirEntry.Fat.Filename));
    }
    else
    {
      memset(&VolumeLabelDirEntry.Fat.Filename[LabelLen], ' ', sizeof(VolumeLabelDirEntry.Fat.Filename) - LabelLen);
    }
    VolumeLabelDirEntry.Fat.Attrib = _A_VOLID;
  }

  pRootFcb = vfatOpenRootFCB(DeviceExt);

  /* Search existing volume entry on disk */
  FileOffset.QuadPart = 0;
  if (CcPinRead(pRootFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry))
  {
    while (TRUE)
    {
      if (ENTRY_VOLUME(DeviceExt, Entry))
      {
        /* Update entry */
        LabelFound = TRUE;
        RtlCopyMemory(Entry, &VolumeLabelDirEntry, SizeDirEntry);
        CcSetDirtyPinnedData(Context, NULL);
        Status = STATUS_SUCCESS;
        break;
      }
      if (ENTRY_END(DeviceExt, Entry))
      {
        break;
      }
      DirIndex++;
      Entry = (PDIR_ENTRY)((ULONG_PTR)Entry + SizeDirEntry);
      if ((DirIndex % EntriesPerPage) == 0)
      {
        CcUnpinData(Context);
        FileOffset.u.LowPart += PAGE_SIZE;
        if (!CcPinRead(pRootFcb->FileObject, &FileOffset, SizeDirEntry, TRUE, &Context, (PVOID*)&Entry))
        {
          Context = NULL;
          break;
        }
      }
    }
    if (Context)
    {
      CcUnpinData(Context);
    }
  }
  if (!LabelFound)
  {
    /* Add new entry for label */
    if (!vfatFindDirSpace(DeviceExt, pRootFcb, 1, &VolumeLabelDirIndex))
      Status = STATUS_DISK_FULL;
    else
    {
      FileOffset.u.HighPart = 0;
      FileOffset.u.LowPart = VolumeLabelDirIndex * SizeDirEntry;
      if (!CcPinRead(pRootFcb->FileObject, &FileOffset, SizeDirEntry,
                 TRUE, &Context, (PVOID*)&Entry))
      {
          Status = STATUS_UNSUCCESSFUL;
      }
      else
      {
          RtlCopyMemory(Entry, &VolumeLabelDirEntry, SizeDirEntry);
          CcSetDirtyPinnedData(Context, NULL);
          CcUnpinData(Context);
          Status = STATUS_SUCCESS;
      }
    }
  }

  vfatReleaseFCB(DeviceExt, pRootFcb);
  if (!NT_SUCCESS(Status))
  {
    return Status;
  }

  /* Update volume label in memory */
  DeviceObject->Vpb->VolumeLabelLength = (USHORT)FsLabelInfo->VolumeLabelLength;
  RtlCopyMemory(DeviceObject->Vpb->VolumeLabel, FsLabelInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabelLength);

  return Status;
}

Generated on Mon May 28 2012 04:49:02 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.