source: trunk/src/lbatest/readsect.c@ 106

Last change on this file since 106 was 106, checked in by Markus Thielen, 14 years ago

fixed a typo in usage; removed unused local variable

File size: 5.8 KB
Line 
1/******************************************************************************
2
3 readsect.c - simple (dumb) HD sector read program
4
5 Author: Markus Thielen
6
7 Compilation (Watcom): wcl386 -bt=os2 readsect.c
8
9 Copyright (c) 2010 by thi.guten Software development, www.thiguten.de
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
25******************************************************************************/
26
27/*---- includes -------------------------------------------------------------*/
28
29#define INCL_DOS
30#define INCL_ERRORS
31#define INCL_DOSDEVICES
32#define INCL_DOSDEVIOCTL
33#include <os2.h>
34#include <stdio.h>
35#include <stddef.h>
36#include <stdlib.h>
37#include <ctype.h>
38#include <string.h>
39#include <errno.h>
40
41#define SECTOR_SIZE 512
42#define SECTORS_PER_READ 4
43
44
45/*--- function prototypes ---------------------------------------------------*/
46
47void usage (void);
48
49int read_sectors (char *drv, unsigned long sectors_to_read,
50 FILE *fpo);
51
52void signal_handler (int sig_no);
53
54/*--- global data -----------------------------------------------------------*/
55
56unsigned long sectors_per_read = SECTORS_PER_READ;
57
58
59/*--- start of code ---------------------------------------------------------*/
60
61/******************************************************************************
62 * main()
63 */
64int main(int argc, char **argv)
65{
66 char drv[50];
67 char *output;
68 FILE *fpo; /* output file */
69 int ret;
70 unsigned long sectors_to_read;
71
72 if (argc < 4) {
73 usage();
74 return -1;
75 }
76
77 if (isalpha(argv[1][0])) {
78 sprintf(drv, "\\\\.\\%c", toupper(argv[1][0]));
79 } else if (isdigit(argv[1][0])) {
80 sprintf(drv, "\\\\.\\Physical_Disk%c", argv[1][0]);
81 } else {
82 usage();
83 return -1;
84 }
85
86 /* get sectors to read */
87 sectors_to_read = strtoul(argv[2], NULL, 10);
88
89 /* get output file */
90 output = argv[3];
91 if (*output == '-' && output[1] == 0) {
92 /* use stdout */
93 fpo = stdout;
94 } else {
95 fpo = fopen(output, "wb");
96 if (!fpo) {
97 perror("Failed to open output file");
98 return(-1);
99 }
100 }
101
102 if (argc > 4) {
103 sectors_per_read = (unsigned long) atoi(argv[4]);
104 if (sectors_per_read == 0) {
105 sectors_per_read = SECTORS_PER_READ;
106 }
107 }
108
109 printf("\nreadsect started; using %d sectors per read\n",
110 (int) sectors_per_read);
111
112 /* go */
113 ret = read_sectors(drv, sectors_to_read, fpo);
114 if (fpo != stdout) {
115 fclose(fpo);
116 }
117
118 return ret;
119
120}
121
122/******************************************************************************
123 * read_sectors() - read sectors and dump to output file
124 */
125int read_sectors(char *drv, unsigned long sectors_to_read, FILE *fpo)
126{
127 unsigned long ret;
128 HFILE hf_disk;
129 unsigned long action;
130 unsigned long cb_read;
131 char *buf;
132 int rc = 0;
133 unsigned long cb_take;
134 unsigned long sectors_take;
135 unsigned long sectors_read = 0;
136
137 buf = calloc(SECTOR_SIZE, sectors_per_read);
138
139 /* open drive */
140 printf("Getting handle for drive %s\n", drv);
141 ret = DosOpen(drv, &hf_disk, &action, 0, 0,
142 OPEN_ACTION_OPEN_IF_EXISTS,
143 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY,
144 NULL);
145 if (ret != NO_ERROR) {
146 fprintf(stderr, "Failed to open disk %s for reading: %d\n", drv, ret);
147 return -1;
148 }
149
150 /* go... */
151 memset(buf, 0x00, sizeof(buf));
152 while (sectors_read < sectors_to_read) {
153
154 sectors_take = min(sectors_to_read - sectors_read, sectors_per_read);
155 cb_take = SECTOR_SIZE * sectors_take;
156
157 ret = DosRead(hf_disk, buf, cb_take, &cb_read);
158 if (ret != NO_ERROR) {
159 fprintf(stderr, "\nFailed to read from disk %s, code %d\n", drv, ret);
160 rc = -1;
161 break;
162 }
163
164 if (cb_read == 0) {
165 break;
166 }
167
168 if (cb_read != cb_take) {
169 printf("\n\nRead only %d instead of %d bytes...\n\n", cb_read, cb_take);
170 break;
171 }
172
173 sectors_read += cb_read / SECTOR_SIZE;
174 if (fwrite(buf, 1, cb_read, fpo) != cb_read) {
175 perror("Failed to write to output file");
176 rc = -1;
177 break;
178 }
179
180 /* progress */
181 printf("\r%d sectors read", sectors_read);
182
183 }
184
185 DosClose(hf_disk);
186 free(buf);
187
188 return rc;
189}
190
191/******************************************************************************
192 * usage() - print usage summary to STDOUT
193 */
194void usage(void)
195{
196 printf("readsect.exe - read HD sectors and store them to an output file.\n"
197 "Call with a drive letter (for logical drive) or 1-based disk number (for\n"
198 "physical drive)\n\n"
199 "Usage:\n\n"
200 "readsect <drive letter|number> <number of sectors> <outfile> [buffer size]\n\n"
201 "where:\n"
202 "drive letter drive letter of logical drive to read from\n"
203 "drive number 1-based physical disk number to read from\n"
204 "number of sectors number of sectors to read (e.g. 1024)\n"
205 "outfile path and filename of output file\n"
206 "buffer size buffer size in number of sectors (512 byte)\n"
207 " (default is %d sectors)\n",
208 SECTORS_PER_READ);
209}
210
211
Note: See TracBrowser for help on using the repository browser.