|
#include <stdio.h> |
|
#include <windows.h> |
|
#include <ddk/ntddk.h> |
|
#include <ddk/ntifs.h> |
|
|
|
void PrintNtError(char *msg, NTSTATUS status) { |
|
char *errmsg; |
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, |
|
NULL, |
|
RtlNtStatusToDosError(status), |
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
|
(LPTSTR) &errmsg, |
|
0, |
|
NULL); |
|
printf("%s: %s\n", msg, errmsg); |
|
LocalFree(errmsg); |
|
} |
|
|
|
void PrintWin32Error(char *msg, DWORD err) { |
|
char *errmsg; |
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, |
|
NULL, |
|
err, |
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
|
(LPTSTR) &errmsg, |
|
0, |
|
NULL); |
|
printf("%s: %s\n", msg, errmsg); |
|
LocalFree(errmsg); |
|
} |
|
|
|
int displayInfo(char *path) { |
|
HANDLE fh; |
|
NTSTATUS st; |
|
IO_STATUS_BLOCK sb; |
|
char buf[1024]; |
|
PFILE_FS_VOLUME_INFORMATION pfi; |
|
|
|
fh = CreateFile(path, |
|
GENERIC_READ, |
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
|
NULL, |
|
OPEN_EXISTING, |
|
0, |
|
NULL); |
|
|
|
if (fh == INVALID_HANDLE_VALUE) { |
|
PrintWin32Error("open(C:)", GetLastError()); |
|
return 1; |
|
} |
|
|
|
st = NtQueryVolumeInformationFile(fh, |
|
&sb, |
|
&buf, |
|
sizeof(buf), |
|
FileFsVolumeInformation); |
|
|
|
if (!NT_SUCCESS(st)) { |
|
PrintNtError("NtQueryVolumeInformationFile", st); |
|
return 1; |
|
} |
|
|
|
pfi = (PFILE_FS_VOLUME_INFORMATION) buf; |
|
int CreationTimeUx; |
|
if (pfi->VolumeCreationTime.QuadPart == 0) |
|
CreationTimeUx = 0; |
|
else |
|
CreationTimeUx = (pfi->VolumeCreationTime.QuadPart / 10000000) - 11644473600; |
|
printf("volume creation time: nt=0x%08lx%08x unix=%u\n", |
|
pfi->VolumeCreationTime.HighPart, |
|
pfi->VolumeCreationTime.LowPart, |
|
CreationTimeUx); |
|
|
|
CloseHandle(fh); |
|
|
|
return 0; |
|
} |
|
|
|
int main(int argc, char *argv[]) { |
|
int i, r = 0, len; |
|
char *path, *p, *q; |
|
|
|
if (argc < 2) { |
|
fprintf(stderr, |
|
"Usage: %s <volume>\n" |
|
"\n" |
|
"<volume> is a volume name in the Win32 namespace; for example,\n" |
|
"\n" |
|
" \\\\?\\C:\n" |
|
" \\\\?\\Volume{590fd828-8520-11df-9c05-0016383a46bf}\n", |
|
argv[0]); |
|
return 2; |
|
} |
|
|
|
for (i = 1; i < argc; i++) { |
|
if (strncmp(argv[i], "\\\\?\\", 4) != 0) { |
|
fprintf(stderr, "error: not a Win32 namespace path: %s\n", argv[i]); |
|
continue; |
|
} |
|
|
|
printf("volume path: %s\n", argv[i]); |
|
r = displayInfo(argv[i]); |
|
printf("\n"); |
|
if (r) |
|
return r; |
|
} |
|
return 0; |
|
} |
Thanks a lot for sharing the code and the pre-built binrary! It is still quite useful :)
Just a hint: DCode may help with converting shown
FILETIME
to a human-readable form.