/* -------------------------------------------------------------------------- *
*
* Copyright 2011 Shao Miller - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
* Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ------------------------------------------------------------------------- */
/****
* ntfstest.c
*
* (C) Shao Miller, 2011
*
* Tests ntfssect.c functions
*
* With special thanks to Mark Roddy for his article:
* http://www.wd-3.com/archive/luserland.htm
*/
#include <windows.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ntfssect.h"
/*** Object types */
/*** Function declarations */
static void show_usage(void);
static void show_last_err(void);
static void show_err(DWORD);
/*** Struct/union definitions */
/*** Function definitions */
/** Program entry-point */
int main(int argc, char ** argv) {
int rc;
DWORD err;
S_NTFSSECT_VOLINFO vol_info;
HANDLE file;
LARGE_INTEGER vcn, lba;
S_NTFSSECT_EXTENT extent;
LONGLONG len;
BOOL ok;
if (argc != 2) {
rc = EXIT_FAILURE;
show_usage();
goto err_args;
}
/* Get volume info */
err = NtfsSectGetVolumeInfoFromFileName(argv[1], &vol_info);
if (err != ERROR_SUCCESS) {
show_err(err);
goto err_vol_info;
}
printf(
"Volume has %d bytes per sector, %d sectors per cluster\n",
vol_info.BytesPerSector,
vol_info.SectorsPerCluster
);
/* Open the file for reading */
file = CreateFile(
argv[1],
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (file == INVALID_HANDLE_VALUE) {
rc = EXIT_FAILURE;
show_last_err();
goto err_file;
}
/* For each extent */
for (
vcn.QuadPart = 0;
NtfsSectGetFileVcnExtent(file, &vcn, &extent) == ERROR_SUCCESS;
vcn = extent.NextVcn
) {
len = extent.NextVcn.QuadPart - extent.FirstVcn.QuadPart;
printf("Extent @ VCN #%lld,", extent.FirstVcn.QuadPart);
printf(" %lld clusters long:\n", len);
printf(" VCN #%lld -", extent.FirstVcn.QuadPart);
printf(" #%lld\n", extent.FirstVcn.QuadPart + len - 1);
printf(" LCN #%lld -", extent.FirstLcn.QuadPart);
printf(" #%lld\n", extent.FirstLcn.QuadPart + len - 1);
err = NtfsSectLcnToLba(
&vol_info,
&extent.FirstLcn,
&lba
);
if (err == ERROR_SUCCESS) {
printf(" LBA #%lld -", lba.QuadPart);
printf(
" #%lld\n",
lba.QuadPart + len * vol_info.SectorsPerCluster
);
}
continue;
}
rc = EXIT_SUCCESS;
CloseHandle(file);
err_file:
CloseHandle(vol_info.Handle);
err_vol_info:
err_args:
return rc;
}
/** Display usage */
static void show_usage(void) {
static const char usage_text[] = "\
File sector info . . . . . . . . . . . . . . . . . . . . Shao Miller, 2011\n\
\n\
Usage: NTFSTEST.EXE <filename>\n\
\n\
Attempts to dump cluster and sector info for <filename>.\n";
printf(usage_text);
return;
}
static void show_last_err(void) {
show_err(GetLastError());
return;
}
/** Display an error */
static void show_err(DWORD err_code) {
void * buf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &buf,
0,
NULL
);
fprintf(stderr, "Error: %s\n", buf);
LocalFree(buf);
return;
}