Skip to content

Commit

Permalink
Align file information allocation size to allocation unit size
Browse files Browse the repository at this point in the history
Add IOCTL_DISK_GET_DRIVE_GEOMETRY_EX and IOCTL_STORAGE_GET_MEDIA_TYPES_EX disk device IOCTL
  • Loading branch information
Maxhy committed Aug 27, 2015
1 parent f95bb48 commit 08b09a3
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 8 deletions.
5 changes: 5 additions & 0 deletions dokan/directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ DokanFillDirInfo(
Buffer->EndOfFile.LowPart = FindData->nFileSizeLow;
Buffer->AllocationSize.HighPart = FindData->nFileSizeHigh;
Buffer->AllocationSize.LowPart = FindData->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&Buffer->AllocationSize);

Buffer->CreationTime.HighPart = FindData->ftCreationTime.dwHighDateTime;
Buffer->CreationTime.LowPart = FindData->ftCreationTime.dwLowDateTime;
Expand Down Expand Up @@ -82,6 +83,7 @@ DokanFillFullDirInfo(
Buffer->EndOfFile.LowPart = FindData->nFileSizeLow;
Buffer->AllocationSize.HighPart = FindData->nFileSizeHigh;
Buffer->AllocationSize.LowPart = FindData->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&Buffer->AllocationSize);

Buffer->CreationTime.HighPart = FindData->ftCreationTime.dwHighDateTime;
Buffer->CreationTime.LowPart = FindData->ftCreationTime.dwLowDateTime;
Expand Down Expand Up @@ -118,6 +120,7 @@ DokanFillIdFullDirInfo(
Buffer->EndOfFile.LowPart = FindData->nFileSizeLow;
Buffer->AllocationSize.HighPart = FindData->nFileSizeHigh;
Buffer->AllocationSize.LowPart = FindData->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&Buffer->AllocationSize);

Buffer->CreationTime.HighPart = FindData->ftCreationTime.dwHighDateTime;
Buffer->CreationTime.LowPart = FindData->ftCreationTime.dwLowDateTime;
Expand Down Expand Up @@ -155,6 +158,7 @@ DokanFillIdBothDirInfo(
Buffer->EndOfFile.LowPart = FindData->nFileSizeLow;
Buffer->AllocationSize.HighPart = FindData->nFileSizeHigh;
Buffer->AllocationSize.LowPart = FindData->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&Buffer->AllocationSize);

Buffer->CreationTime.HighPart = FindData->ftCreationTime.dwHighDateTime;
Buffer->CreationTime.LowPart = FindData->ftCreationTime.dwLowDateTime;
Expand Down Expand Up @@ -192,6 +196,7 @@ DokanFillBothDirInfo(
Buffer->EndOfFile.LowPart = FindData->nFileSizeLow;
Buffer->AllocationSize.HighPart = FindData->nFileSizeHigh;
Buffer->AllocationSize.LowPart = FindData->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&Buffer->AllocationSize);

Buffer->CreationTime.HighPart = FindData->ftCreationTime.dwHighDateTime;
Buffer->CreationTime.LowPart = FindData->ftCreationTime.dwLowDateTime;
Expand Down
7 changes: 7 additions & 0 deletions dokan/dokan.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ GetRawDeviceName(LPCWSTR DeviceName)
return rawDeviceName;
}

void
ALIGN_ALLOCATION_SIZE(PLARGE_INTEGER size)
{
long long r = size->QuadPart % DOKAN_ALLOCATION_UNIT_SIZE;
size->QuadPart = (size->QuadPart + (r > 0 ? DOKAN_ALLOCATION_UNIT_SIZE - r : 0));
}

UINT WINAPI
DokanLoop(
PDOKAN_INSTANCE DokanInstance
Expand Down
3 changes: 3 additions & 0 deletions dokan/dokani.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ SendToDevice(
LPCWSTR
GetRawDeviceName(LPCWSTR DeviceName);

void
ALIGN_ALLOCATION_SIZE(PLARGE_INTEGER size);

UINT __stdcall
DokanLoop(
PVOID Param);
Expand Down
2 changes: 2 additions & 0 deletions dokan/fileinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ DokanFillFileStandardInfo(

StandardInfo->AllocationSize.HighPart = FileInfo->nFileSizeHigh;
StandardInfo->AllocationSize.LowPart = FileInfo->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&StandardInfo->AllocationSize);
StandardInfo->EndOfFile.HighPart = FileInfo->nFileSizeHigh;
StandardInfo->EndOfFile.LowPart = FileInfo->nFileSizeLow;
StandardInfo->NumberOfLinks = FileInfo->nNumberOfLinks;
Expand Down Expand Up @@ -218,6 +219,7 @@ DokanFillNetworkOpenInfo(
NetInfo->ChangeTime.HighPart = FileInfo->ftLastWriteTime.dwHighDateTime;
NetInfo->AllocationSize.HighPart= FileInfo->nFileSizeHigh;
NetInfo->AllocationSize.LowPart = FileInfo->nFileSizeLow;
ALIGN_ALLOCATION_SIZE(&NetInfo->AllocationSize);
NetInfo->EndOfFile.HighPart = FileInfo->nFileSizeHigh;
NetInfo->EndOfFile.LowPart = FileInfo->nFileSizeLow;
NetInfo->FileAttributes = FileInfo->dwFileAttributes;
Expand Down
80 changes: 73 additions & 7 deletions sys/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,20 @@ GlobalDeviceControl(
return status;
}

VOID
DokanPopulateDiskGeometry(
__in PDISK_GEOMETRY diskGeometry
)
{
ULONG length;

length = 1024 * 1024 * 1024;
diskGeometry->Cylinders.QuadPart = length / DOKAN_SECTOR_SIZE / 32 / 2;
diskGeometry->MediaType = FixedMedia;
diskGeometry->TracksPerCylinder = 2;
diskGeometry->SectorsPerTrack = 32;
diskGeometry->BytesPerSector = DOKAN_SECTOR_SIZE;
}

NTSTATUS
DiskDeviceControl(
Expand Down Expand Up @@ -136,7 +150,6 @@ DiskDeviceControl(
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
{
PDISK_GEOMETRY diskGeometry;
ULONG length;

DDbgPrint(" IOCTL_DISK_GET_DRIVE_GEOMETRY\n");
if (outputLength < sizeof(DISK_GEOMETRY)) {
Expand All @@ -148,18 +161,71 @@ DiskDeviceControl(
diskGeometry = (PDISK_GEOMETRY)Irp->AssociatedIrp.SystemBuffer;
ASSERT(diskGeometry != NULL);

length = 1024*1024*1024;
diskGeometry->Cylinders.QuadPart = length / DOKAN_SECTOR_SIZE / 32 / 2;
diskGeometry->MediaType = FixedMedia;
diskGeometry->TracksPerCylinder = 2;
diskGeometry->SectorsPerTrack = 32;
diskGeometry->BytesPerSector = DOKAN_SECTOR_SIZE;
DokanPopulateDiskGeometry(diskGeometry);

status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
}
break;

case IOCTL_DISK_GET_DRIVE_GEOMETRY_EX:
{
PDISK_GEOMETRY_EX diskGeometry;

DDbgPrint(" IOCTL_DISK_GET_DRIVE_GEOMETRY_EX\n");
if (outputLength < sizeof(DISK_GEOMETRY_EX)) {
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}

diskGeometry = (PDISK_GEOMETRY_EX)Irp->AssociatedIrp.SystemBuffer;
ASSERT(diskGeometry != NULL);

DokanPopulateDiskGeometry(&(diskGeometry->Geometry));
diskGeometry->DiskSize.QuadPart = 1024 * 1024 * 1024; // TODO: This should be get from dcb, like dcb->PartitionLength (cached from DokanOperations->GetDiskFreeSpace ?)

status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(DISK_GEOMETRY_EX);
}
break;

case IOCTL_STORAGE_GET_MEDIA_TYPES_EX:
{
PGET_MEDIA_TYPES mediaTypes = NULL;
PDEVICE_MEDIA_INFO mediaInfo = NULL; //&mediaTypes->MediaInfo[0];

// We alway return only one media type
DDbgPrint(" IOCTL_STORAGE_GET_MEDIA_TYPES_EX\n");
if (outputLength < sizeof(GET_MEDIA_TYPES)) {
status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = 0;
break;
}

mediaTypes = (PGET_MEDIA_TYPES)Irp->AssociatedIrp.SystemBuffer;
ASSERT(mediaTypes != NULL);

mediaInfo = &mediaTypes->MediaInfo[0];

mediaTypes->DeviceType = FILE_DEVICE_VIRTUAL_DISK;
mediaTypes->MediaInfoCount = 1;

DISK_GEOMETRY diskGeometry;
DokanPopulateDiskGeometry(&diskGeometry);
mediaInfo->DeviceSpecific.DiskInfo.MediaType = diskGeometry.MediaType;
mediaInfo->DeviceSpecific.DiskInfo.NumberMediaSides = 1;
mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE);
mediaInfo->DeviceSpecific.DiskInfo.Cylinders.QuadPart = diskGeometry.Cylinders.QuadPart;
mediaInfo->DeviceSpecific.DiskInfo.TracksPerCylinder = diskGeometry.TracksPerCylinder;
mediaInfo->DeviceSpecific.DiskInfo.SectorsPerTrack = diskGeometry.SectorsPerTrack;
mediaInfo->DeviceSpecific.DiskInfo.BytesPerSector = diskGeometry.BytesPerSector;

status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(GET_MEDIA_TYPES);
}
break;

case IOCTL_DISK_GET_LENGTH_INFO:
{
PGET_LENGTH_INFORMATION getLengthInfo;
Expand Down
1 change: 0 additions & 1 deletion sys/public.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#define DOKAN_SECTOR_SIZE 512
#define DOKAN_ALLOCATION_UNIT_SIZE 512


// used in CCB->Flags and FCB->Flags
#define DOKAN_FILE_DIRECTORY 1
#define DOKAN_FILE_DELETED 2
Expand Down

0 comments on commit 08b09a3

Please sign in to comment.