Author Topic: Is my file on a SSD?  (Read 733 times)

Biterider

  • Moderator
  • Member
  • *****
  • Posts: 730
  • ObjAsm Developer
    • ObjAsm
Is my file on a SSD?
« on: January 11, 2021, 05:56:43 AM »
Hi
Taking a break from a major project, I came across a post by Raymond Chen that explains very well how to infer whether or not a file is on a SSD, looking a the seek penalty of a drive.
https://devblogs.microsoft.com/oldnewthing/20201023-00/?p=104395

It takes a few steps to get this information.

Since it caught my attention, I translated it into asm and stepped into an old problem.
Structures used to communicate with the kernel are almost always aligned 8 bytes long, regardless of the bitness of your application. I had to adjust some structures (VOLUME_DISK_EXTENTS, STORAGE_PROPERTY_QUERY, DEVICE_SEEK_PENALTY_DESCRIPTOR, etc.) in the winioctl.inc file to use the API correctly.

Code: [Select]
IsFileOnSSD proc pFilePath:PSTRING
  local hVolume:HANDLE, hDisk:HANDLE, dBytesWritten:DWORD
  local Query:STORAGE_PROPERTY_QUERY
  local Result:DEVICE_SEEK_PENALTY_DESCRIPTOR

  invoke GetVolumeHandleForFile, pFilePath
  .if xax != 0
    mov hVolume, xax
    mov Result.IncursSeekPenalty, -1                    ;Set error value
    invoke GetFirstPhysicalDiskHandleForVolume, hVolume
    .if xax != 0
      mov hDisk, xax
      mov Query.PropertyId, StorageDeviceSeekPenaltyProperty
      mov Query.QueryType, PropertyStandardQuery

      invoke DeviceIoControl, hDisk, IOCTL_STORAGE_QUERY_PROPERTY, \
                              addr Query, sizeof Query, addr Result, sizeof Result, \
                              addr dBytesWritten, NULL
      invoke CloseHandle, hDisk
    .endif
    invoke CloseHandle, hVolume
   
    movsx eax, Result.IncursSeekPenalty                 ;Prepare the return value
    .if eax == 0                                        ;eax = TRUE, FALSE or -1 if failed
      inc eax
    .elseif eax != -1
      xor eax, eax
    .endif
  .else
    mov eax, -1
  .endif
  ret
IsFileOnSSD endp

I'm adding this file and project for reference for those who need such functionality.

Biterider