| /* -------------------------------------------------------------------------- * |
| * |
| * 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; |
| } |
| |