win: Use lower-case private definition of STORAGE_DEVICE_NUMBER
[profile/ivi/syslinux.git] / win / ntfstest.c
1 /* -------------------------------------------------------------------------- *
2  *
3  *   Copyright 2011 Shao Miller - All Rights Reserved
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8  *   Boston MA 02111-1307, USA; either version 2 of the License, or
9  *   (at your option) any later version; incorporated herein by reference.
10  *
11  * ------------------------------------------------------------------------- */
12
13 /****
14  * ntfstest.c
15  *
16  * (C) Shao Miller, 2011
17  *
18  * Tests ntfssect.c functions
19  *
20  * With special thanks to Mark Roddy for his article:
21  *   http://www.wd-3.com/archive/luserland.htm
22  */
23 #include <windows.h>
24 #include <stddef.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "ntfssect.h"
30
31 /*** Object types */
32
33 /*** Function declarations */
34 static void show_usage(void);
35 static void show_last_err(void);
36 static void show_err(DWORD);
37
38 /*** Struct/union definitions */
39
40 /*** Function definitions */
41
42 /** Program entry-point */
43 int main(int argc, char ** argv) {
44     int rc;
45     DWORD err;
46     S_NTFSSECT_VOLINFO vol_info;
47     HANDLE file;
48     LARGE_INTEGER vcn, lba;
49     S_NTFSSECT_EXTENT extent;
50     LONGLONG len;
51     BOOL ok;
52
53     if (argc != 2) {
54         rc = EXIT_FAILURE;
55         show_usage();
56         goto err_args;
57       }
58
59     /* Get volume info */
60     err = NtfsSectGetVolumeInfoFromFileName(argv[1], &vol_info);
61     if (err != ERROR_SUCCESS) {
62         show_err(err);
63         goto err_vol_info;
64       }
65     printf(
66         "Volume has %d bytes per sector, %d sectors per cluster\n",
67         vol_info.BytesPerSector,
68         vol_info.SectorsPerCluster
69       );
70
71     /* Open the file for reading */
72     file = CreateFile(
73         argv[1],
74         GENERIC_READ,
75         FILE_SHARE_READ,
76         NULL,
77         OPEN_EXISTING,
78         0,
79         NULL
80       );
81     if (file == INVALID_HANDLE_VALUE) {
82         rc = EXIT_FAILURE;
83         show_last_err();
84         goto err_file;
85       }
86
87     /* For each extent */
88     for (
89         vcn.QuadPart = 0;
90         NtfsSectGetFileVcnExtent(file, &vcn, &extent) == ERROR_SUCCESS;
91         vcn = extent.NextVcn
92       ) {
93         len = extent.NextVcn.QuadPart - extent.FirstVcn.QuadPart;
94         printf("Extent @ VCN #%lld,", extent.FirstVcn.QuadPart);
95         printf(" %lld clusters long:\n", len);
96         printf("  VCN #%lld -", extent.FirstVcn.QuadPart);
97         printf(" #%lld\n", extent.FirstVcn.QuadPart + len - 1);
98         printf("  LCN #%lld -", extent.FirstLcn.QuadPart);
99         printf(" #%lld\n", extent.FirstLcn.QuadPart + len - 1);
100         err = NtfsSectLcnToLba(
101             &vol_info,
102             &extent.FirstLcn,
103             &lba
104           );
105         if (err == ERROR_SUCCESS) {
106             printf("  LBA #%lld -", lba.QuadPart);
107             printf(
108                 " #%lld\n",
109                 lba.QuadPart + len * vol_info.SectorsPerCluster
110               );
111           }
112         continue;
113       }
114
115     rc = EXIT_SUCCESS;
116
117     CloseHandle(file);
118     err_file:
119
120     CloseHandle(vol_info.Handle);
121     err_vol_info:
122
123     err_args:
124
125     return rc;
126   }
127
128 /** Display usage */
129 static void show_usage(void) {
130     static const char usage_text[] = "\
131   File sector info . . . . . . . . . . . . . . . . . . . . Shao Miller, 2011\n\
132 \n\
133   Usage: NTFSTEST.EXE <filename>\n\
134 \n\
135   Attempts to dump cluster and sector info for <filename>.\n";
136
137     printf(usage_text);
138     return;
139   }
140
141 static void show_last_err(void) {
142     show_err(GetLastError());
143     return;
144   }
145
146 /** Display an error */
147 static void show_err(DWORD err_code) {
148     void * buf;
149
150     FormatMessage(
151         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
152         NULL,
153         err_code,
154         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
155         (LPTSTR) &buf,
156         0,
157         NULL
158       );
159     fprintf(stderr, "Error: %s\n", buf);
160     LocalFree(buf);
161     return;
162   }
163