#include #include #include #define _WIN32_WINNT 0x0600 #include #include #include #ifndef FILE_READ_ONLY_VOLUME #define FILE_READ_ONLY_VOLUME 0x80000 #endif #ifndef FILE_SEQUENTIAL_WRITE_ONCE #define FILE_SEQUENTIAL_WRITE_ONCE 0x100000 #endif #ifndef FILE_SUPPORTS_TRANSACTIONS #define FILE_SUPPORTS_TRANSACTIONS 0x200000 #endif typedef struct _FILE_FS_OBJECTID_INFORMATION { UCHAR ObjectId[16]; UCHAR ExtendedInfo[48]; } FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR); BOOLEAN NTAPI RtlTimeToSecondsSince1970 (PLARGE_INTEGER, PULONG); int __stdcall sys_wcstombs (char *tgt, int tlen, const WCHAR *src, int slen) { int ret; ret = WideCharToMultiByte (GetOEMCP (), 0, src, slen, tgt, tlen, NULL, NULL); if (ret) tgt[ret < tlen ? ret : tlen - 1] = '\0'; return ret; } #define SAMBA_EXTENDED_INFO_MAGIC 0x536d4261 /* "SmBa" */ #define SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH 28 #pragma pack(push,4) struct smb_extended_info { DWORD samba_magic; /* Always SAMBA_EXTRA_INFO_MAGIC */ DWORD samba_version; /* Major/Minor/Release/Revision */ DWORD samba_subversion; /* Prerelease/RC/Vendor patch */ LARGE_INTEGER samba_gitcommitdate; char samba_version_string[SAMBA_EXTENDED_INFO_VERSION_STRING_LENGTH]; }; #pragma pack(pop) void print_objectid (PFILE_FS_OBJECTID_INFORMATION pfi) { struct smb_extended_info *ei = (struct smb_extended_info *) &pfi->ExtendedInfo; time_t t; int i; printf ("Object Id : "); for (i = 0; i < 16; ++i) printf ("%02x ", pfi->ObjectId[i]); puts (""); printf ("Extended Info : "); if (ei->samba_magic == SAMBA_EXTENDED_INFO_MAGIC) { printf ("Samba!!!\n"); printf (" : magic <%08lx>\n", ei->samba_magic); printf (" : version <%08lx>\n", ei->samba_version); printf (" : subversion <%08lx>\n", ei->samba_subversion); RtlTimeToSecondsSince1970 (&ei->samba_gitcommitdate, &t); printf (" : GIT commit <%.24s>\n", ctime (&t)); printf (" : version string <%s>", ei->samba_version_string); } else printf ("Not Samba"); for (i = 0; i < 48; ++i) { if (i == 0 || i == 16 || i == 32) printf ("\n "); printf ("%02x ", pfi->ExtendedInfo[i]); } puts (""); } int main (int argc, char **argv) { char winpath[256]; DWORD flags = 0; HANDLE h; UNICODE_STRING wpath; UNICODE_STRING upath; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; NTSTATUS stat; ULONG ret; char buf[1024]; char name[256]; if (argc < 2) { fprintf (stderr, "usage: %s path\n", argv[0]); return 1; } cygwin_conv_to_full_win32_path (argv[1], winpath); if (!RtlCreateUnicodeStringFromAsciiz (&wpath, winpath)) { fprintf (stderr, "RtlCreateUnicodeStringFromAsciiz failed\n"); return 1; } if (!RtlDosPathNameToNtPathName_U (wpath.Buffer, &upath, NULL, NULL)) { fprintf (stderr, "RtlDosPathNameToNtPathName_U failed\n"); RtlFreeUnicodeString (&wpath); return 1; } InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL); stat = ZwOpenFile (&h, READ_CONTROL, &attr, &io, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS (stat) && stat == STATUS_NO_MEDIA_IN_DEVICE) { upath.Length = 6 * sizeof (WCHAR); stat = ZwOpenFile (&h, READ_CONTROL, &attr, &io, FILE_SHARE_VALID_FLAGS, 0); } if (!NT_SUCCESS (stat)) { char buf[1024]; wcstombs (buf, upath.Buffer, upath.Length / sizeof (WCHAR)); buf[upath.Length / sizeof (WCHAR)] = '\0'; fprintf (stderr, "ZwOpenFile(%s) failed, %08x\n", buf, stat); return 1; } stat = ZwQueryVolumeInformationFile (h, &io, buf, 1024, FileFsDeviceInformation); if (NT_SUCCESS (stat)) { PFILE_FS_DEVICE_INFORMATION pfi = (PFILE_FS_DEVICE_INFORMATION) buf; printf ("Device Type : %lx\n", pfi->DeviceType); printf ("Characteristics : %lx\n", pfi->Characteristics); } else fprintf (stderr, "FileFsDeviceInformation failed, %08lx\n", stat); stat = ZwQueryVolumeInformationFile (h, &io, buf, 1024, FileFsObjectIdInformation); if (NT_SUCCESS (stat)) print_objectid ((PFILE_FS_OBJECTID_INFORMATION) buf); else fprintf (stderr, "FileFsObjectIdInformation failed, %08lx\n", stat); stat = ZwQueryVolumeInformationFile (h, &io, buf, 1024, FileFsVolumeInformation); if (NT_SUCCESS (stat)) { PFILE_FS_VOLUME_INFORMATION pfi = (PFILE_FS_VOLUME_INFORMATION) buf; if (pfi->VolumeLabelLength) { sys_wcstombs (name, 256, pfi->VolumeLabel, pfi->VolumeLabelLength / sizeof (WCHAR)); printf ("Volume Name : <%s>\n", name); } else printf ("Volume Name : <>\n"); printf ("Serial Number : %lu\n", pfi->VolumeSerialNumber); } else fprintf (stderr, "FileFsVolumeInformation failed, %08lx\n", stat); stat = ZwQueryVolumeInformationFile (h, &io, buf, 1024, FileFsAttributeInformation); if (NT_SUCCESS (stat)) { PFILE_FS_ATTRIBUTE_INFORMATION pfi = (PFILE_FS_ATTRIBUTE_INFORMATION) buf; printf ("Max Filenamelength : %lu\n",pfi->MaximumComponentNameLength); sys_wcstombs (name, 256, pfi->FileSystemName, pfi->FileSystemNameLength / sizeof (WCHAR)); printf ("Filesystemname : <%s>\n", name); printf ("Flags : %lx\n", flags = pfi->FileSystemAttributes); printf (" FILE_CASE_SENSITIVE_SEARCH : %s\n", (flags & FILE_CASE_SENSITIVE_SEARCH) ? "TRUE" : "FALSE"); printf (" FILE_CASE_PRESERVED_NAMES : %s\n", (flags & FILE_CASE_PRESERVED_NAMES) ? "TRUE" : "FALSE"); printf (" FILE_UNICODE_ON_DISK : %s\n", (flags & FILE_UNICODE_ON_DISK) ? "TRUE" : "FALSE"); printf (" FILE_PERSISTENT_ACLS : %s\n", (flags & FILE_PERSISTENT_ACLS) ? "TRUE" : "FALSE"); printf (" FILE_FILE_COMPRESSION : %s\n", (flags & FILE_FILE_COMPRESSION) ? "TRUE" : "FALSE"); printf (" FILE_VOLUME_QUOTAS : %s\n", (flags & FILE_VOLUME_QUOTAS) ? "TRUE" : "FALSE"); printf (" FILE_SUPPORTS_SPARSE_FILES : %s\n", (flags & FILE_SUPPORTS_SPARSE_FILES) ? "TRUE" : "FALSE"); printf (" FILE_SUPPORTS_REPARSE_POINTS: %s\n", (flags & FILE_SUPPORTS_REPARSE_POINTS) ? "TRUE" : "FALSE"); printf (" FILE_SUPPORTS_REMOTE_STORAGE: %s\n", (flags & FILE_SUPPORTS_REMOTE_STORAGE) ? "TRUE" : "FALSE"); printf (" FILE_VOLUME_IS_COMPRESSED : %s\n", (flags & FILE_VOLUME_IS_COMPRESSED) ? "TRUE" : "FALSE"); printf (" FILE_SUPPORTS_OBJECT_IDS : %s\n", (flags & FILE_SUPPORTS_OBJECT_IDS) ? "TRUE" : "FALSE"); printf (" FILE_SUPPORTS_ENCRYPTION : %s\n", (flags & FILE_SUPPORTS_ENCRYPTION) ? "TRUE" : "FALSE"); printf (" FILE_NAMED_STREAMS : %s\n", (flags & FILE_NAMED_STREAMS) ? "TRUE" : "FALSE"); printf (" FILE_READ_ONLY_VOLUME : %s\n", (flags & FILE_READ_ONLY_VOLUME) ? "TRUE" : "FALSE"); printf (" FILE_SEQUENTIAL_WRITE_ONCE : %s\n", (flags & FILE_SEQUENTIAL_WRITE_ONCE) ? "TRUE" : "FALSE"); printf (" FILE_SUPPORTS_TRANSACTIONS : %s\n", (flags & FILE_SUPPORTS_TRANSACTIONS) ? "TRUE" : "FALSE"); } else fprintf (stderr, "FileFsAttributeInformation failed, %08lx\n", stat); ZwClose (h); RtlFreeUnicodeString (&upath); RtlFreeUnicodeString (&wpath); return 0; }