Skip to content

Instantly share code, notes, and snippets.

@reinsteam
Created August 28, 2015 23:17
Show Gist options
  • Save reinsteam/189da02f9e8b66ddb35e to your computer and use it in GitHub Desktop.
Save reinsteam/189da02f9e8b66ddb35e to your computer and use it in GitHub Desktop.
Sample code of volumes enumeration to get physical and logical sector alignment
#pragma warning (push)
/* 4820: '<struct-name>' : 'n' bytes padding added after data member '<member-name>'*/
# pragma warning (disable : 4820)
# pragma warning (disable : 4255 4668)
# include <windows.h>
# include <stdio.h>
#pragma warning (pop)
typedef unsigned u32;
#ifndef NO_INLINE
# define NO_INLINE __declspec(noinline)
#endif
static u32 _max_align_phys = 0;
static u32 _max_align_logic = 0;
static NO_INLINE u32 is_volume_guid_valid(const char * guid, u32 guid_size)
{
return ( guid[0] == '\\' && guid[1] == '\\' && guid[2] == '?' && guid[3] == '\\' && guid[guid_size - 1] == '\\');
}
static NO_INLINE u32 volume_guid_to_name(char * guid, u32 guid_size, char * name, u32 name_size)
{
DWORD size = 0;
guid[ guid_size - 1 ] = '\0';
size = QueryDosDevice(&guid[4], name, name_size);
guid[ guid_size - 1 ] = '\\';
return size;
}
static NO_INLINE u32 volume_guid_to_path(const char * name, u32 name_size, char * path, u32 path_size)
{
((void)name_size);
if ( GetVolumePathNamesForVolumeName(name, path, path_size, &path_size) )
{
return path_size;
}
return 0;
}
static NO_INLINE u32 sector_desc(const char * name, u32 * align_phys, u32 * align_logic)
{
STORAGE_PROPERTY_QUERY query;
STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR desc;
DWORD bytes;
u32 result = 0;
HANDLE device = CreateFile(name, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if ( device != INVALID_HANDLE_VALUE )
{
query.PropertyId = StorageAccessAlignmentProperty;
query.QueryType = PropertyStandardQuery;
if ( DeviceIoControl(device, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), &desc, sizeof(desc), &bytes, 0) )
{
*align_phys = desc.BytesPerPhysicalSector;
*align_logic = desc.BytesPerLogicalSector;
result = 1;
}
CloseHandle(device);
}
return result;
}
typedef void (*on_partition)(char * guid, u32 guid_size);
static NO_INLINE void enumerate_partitions(char * guid, u32 guid_size, on_partition cback)
{
HANDLE handle = FindFirstVolume(guid, guid_size);
if ( handle != INVALID_HANDLE_VALUE )
{
cback( guid, (u32)strlen(guid) );
while ( FindNextVolume(handle, guid, guid_size) )
{
cback( guid, (u32)strlen(guid) );
}
FindVolumeClose(handle);
}
}
static NO_INLINE void partition(char * guid, u32 guid_size)
{
u32 align_phys = 0;
u32 align_logic = 0;
char name[32];
char path[32];
u32 name_size = 0;
u32 path_size = 0;
if ( is_volume_guid_valid(guid, guid_size) )
{
name_size = volume_guid_to_name(guid, guid_size, name, sizeof(name));
path_size = volume_guid_to_path(guid, guid_size, path, sizeof(path));
}
guid[ guid_size - 1 ] = '\0';
if ( sector_desc(guid, &align_phys, &align_logic) )
{
_max_align_phys = (align_phys > _max_align_phys ) ? align_phys : _max_align_phys;
_max_align_logic = (align_logic > _max_align_logic) ? align_logic : _max_align_logic;
}
printf("%s | %-23s | %-6s | %12u bytes | %11u bytes |\n", guid, name, path, align_phys, align_logic);
}
int main(void)
{
char guid[128];
printf("%-48s | %-23s | %-6s | %s | %s |\n", "GUID", "Name", "Path", "Physical Alignment", "Logical Alignment");
enumerate_partitions(guid, sizeof(guid), &partition);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment