Develop and Download Open Source Software

Browse CVS Repository

Contents of /enbanfukusyaya/EnbanFukusyaYa/DriveAccess/drive.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.16 - (show annotations) (download) (as text)
Fri Nov 5 17:24:03 2010 UTC (13 years, 5 months ago) by bananajinn
Branch: MAIN
CVS Tags: HEAD
Changes since 1.15: +4 -4 lines
File MIME type: text/x-csrc
*** empty log message ***

1 /*
2 * @file drive.c
3 * @brief ドライブアクセス
4 * @author BananaJinn
5 * @version $Id: drive.c,v 1.15 2010/11/01 14:34:11 bananajinn Exp $
6 * 円盤複写屋
7 * Copyright (C) 2004-2006 BananaJinn<banana@mxh.mesh.ne.jp>.
8 */
9
10 #include <stdio.h>
11 #if !defined(WIN32)
12 # include <stdlib.h>
13 # include <string.h>
14 #endif
15
16 #include "mem.h"
17 #include "drive.h"
18 #include "cmdlog.h"
19 #include "cmd.h"
20 #include "ui.h"
21 #include "text.h"
22 #include "log.h"
23
24 /**
25 * @brief ドライブにコマンドを送信する
26 * @param[in] drive 送信先ドライブ
27 * @parma[in] cdb CDB
28 * @param[in] buflen コマンドに付随するデータの転送サイズ
29 * @param[in] reqflag データ転送方向
30 * (REQ_NODATA:データ転送なし, REQ_DATAOUT:データ送信, REQ_DATAIN:データ受信)
31 * @retval RET_OK コマンド成功
32 * @retval RET_NG コマンド失敗
33 */
34 int SendCmd(CMDDRIVE *drive, BYTE *cdb, DWORD buflen, BYTE reqflag)
35 {
36 int ret;
37
38 if(drive->cmd_type == CMDDRVCTYPE_UNKNOWN){
39 drive->cmd_type = CMDDRVCTYPE_CHECKING;
40 CheckAtapi(drive);
41 }
42
43 drive->cmdcode = cdb[0];
44 if(drive->type == CMDDRVTYPE_DRIVE){
45 ret = SendAspiCmd(&drive->u.drive, cdb, drive->data_buf, buflen,
46 drive->sense_data, sizeof(drive->sense_data), reqflag);
47 }
48 else if(drive->type == CMDDRVTYPE_NET){
49 ret = SendNetCmd(&drive->u.net, cdb, drive->data_buf, buflen,
50 drive->sense_data, sizeof(drive->sense_data), reqflag);
51 }
52 else{
53 return RET_NG;
54 }
55 CmdLog(drive, cdb, buflen, reqflag, ret);
56 #ifdef DEBUGCMD
57 DebugLog("SendCmd: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X len=0x%08lX io=%d\n",
58 cdb[0], cdb[1], cdb[2], cdb[3], cdb[4], cdb[5],
59 cdb[6], cdb[7], cdb[8], cdb[9], cdb[10], cdb[11],
60 buflen, reqflag);
61 #endif
62
63 if(ret != RET_OK){
64 DebugLog("SendCmd: Command error. cmd=%02Xh %X-%02X-%02X\n",
65 cdb[0], SD_SENSEKEY(drive), SD_ASC(drive), SD_ASCQ(drive));
66 }
67
68 return ret;
69 }
70
71 /**
72 * @brief 長い読み込み要求を送信する
73 * @param[in] drive 送信先ドライブ
74 * @param[in] cdb CDB
75 * @param[in] buflen データ転送サイズ
76 * @param[in] reqflag データ転送方向
77 * (REQ_NODATA:データ送信なし, REQ_DATAOUT:データ送信, REQ_DATAIN:データ受信)
78 * @param[in] total_blocks 転送ブロック数
79 * @retval RET_OK コマンド成功
80 * @retval RET_NG コマンド失敗
81 */
82 int SendCmdLongRead(CMDDRIVE *drive, BYTE *cdb, DWORD buflen, BYTE reqflag,
83 DWORD total_blocks)
84 {
85 int ret;
86
87 if(drive->cmd_type == CMDDRVCTYPE_UNKNOWN){
88 drive->cmd_type = CMDDRVCTYPE_CHECKING;
89 CheckAtapi(drive);
90 }
91
92 if(drive->type == CMDDRVTYPE_NET){
93 ret = SendNetCmdLongRead(&drive->u.net, cdb, drive->data_buf, buflen,
94 drive->sense_data, sizeof(drive->sense_data),
95 reqflag, total_blocks);
96 }
97 else{
98 return RET_NG;
99 }
100
101 CmdLog(drive, cdb, buflen, reqflag, ret);
102
103 return ret;
104 }
105
106 /**
107 * @brief ドライブに対する初期設定を行う
108 * @param[in] drive ドライブ
109 * @param[in] bufsize 転送バッファーサイズ(バイト数)
110 * @param[in] cmdlog_size ログサイズ(レコード数)
111 * @param[in] type ドライブ種別(CMDDRVTYPE_*)
112 * @retval RET_OK 成功
113 * @retval RET_NG 失敗
114 */
115 int InitializeCmdDrive(CMDDRIVE *drive, int bufsize, int cmdlog_size, int type)
116 {
117 int ret = RET_NG;
118
119 if(type != CMDDRVTYPE_DRIVE && type != CMDDRVTYPE_NET &&
120 type != CMDDRVTYPE_IMAGE && type != CMDDRVTYPE_ISO &&
121 type != CMDDRVTYPE_MKISOFS){
122 return RET_NG;
123 }
124
125 FreeCmdDrive(drive);
126 drive->cmd_type = CMDDRVCTYPE_UNKNOWN;
127
128 if(CmdLogInit(drive, cmdlog_size)!=RET_OK){
129 return RET_NG;
130 }
131
132 if(bufsize>0){
133 drive->data_buf = (BYTE *)MemNew(bufsize);
134 if(drive->data_buf==NULL){
135 return RET_NG;
136 }
137 drive->bufsize = bufsize;
138 drive->own_alloc = TRUE;
139 }
140
141 ret = RET_NG;
142 drive->type = type;
143 if(type == CMDDRVTYPE_DRIVE){
144 ret = InitializeDrive(&drive->u.drive);
145 }
146 else if(type == CMDDRVTYPE_NET){
147 ret = InitializeSOCKCB(&drive->u.net);
148 }
149 else if(type == CMDDRVTYPE_IMAGE){
150 ret = InitializeImage(&drive->u.image);
151 }
152 else if(type == CMDDRVTYPE_ISO){
153 ret = InitializeImage(&drive->u.image);
154 }
155 else if(type == CMDDRVTYPE_MKISOFS){
156 ret = MIFInitialize(&drive->u.mkisofs);
157 }
158 if(ret != RET_OK){
159 if(drive->own_alloc){
160 MemFree(drive->data_buf);
161 drive->data_buf=NULL;
162 }
163 MemFree(drive->cmdlog);
164 drive->cmdlog=NULL;
165 return ret;
166 }
167
168 return RET_OK;
169 }
170
171 /**
172 * @brief 使用済みドライブの開放処理を行う
173 * @param[in] drive ドライブ
174 */
175 void FreeCmdDrive(CMDDRIVE *drive)
176 {
177 CmdLogFree(drive);
178 if(drive->data_buf!=NULL){
179 if(drive->own_alloc){
180 MemFree(drive->data_buf);
181 }
182 drive->data_buf=NULL;
183 }
184
185 if(drive->type == CMDDRVTYPE_DRIVE){
186 FreeDrive(&drive->u.drive);
187 }
188 else if(drive->type == CMDDRVTYPE_NET){
189 FreeSOCKCB(&drive->u.net);
190 }
191 else if(drive->type == CMDDRVTYPE_IMAGE){
192 FreeImage(&drive->u.image);
193 }
194 else if(drive->type == CMDDRVTYPE_ISO){
195 FreeImage(&drive->u.image);
196 }
197 else if(drive->type == CMDDRVTYPE_MKISOFS){
198 MIFFree(&drive->u.mkisofs);
199 }
200 }
201
202 /**
203 * @brief ATAPIドライブかどうかを判断する
204 * 判断結果はdriveの構造体に保持される。
205 * @param[in] drive ドライブ
206 */
207 void CheckAtapi(CMDDRIVE *drive)
208 {
209 BYTE cdb[12];
210 BYTE buf[12];
211 BYTE *keep;
212 int ret;
213
214 keep = drive->data_buf;
215 drive->data_buf = buf;
216
217 memset(cdb, 0, sizeof(cdb));
218 cdb[0] = CMD_MODE_SENSE10;
219 cdb[2] = 0x2a;
220 cdb[8] = 12;
221 ret = SendCmd(drive, cdb, 12, REQ_DATAIN);
222 if(ret!=RET_OK){
223 drive->cmd_type = CMDDRVCTYPE_SCSI;
224 }
225 else{
226 drive->cmd_type = (drive->data_buf[8]==0x2a ? CMDDRVCTYPE_ATAPI:CMDDRVCTYPE_SCSI);
227 }
228
229 drive->data_buf = keep;
230 }
231
232 /**
233 * @brief ドライブにホストアダプタNoやターゲットID、タイムアウトを指定する
234 * @param[in] drive ドライブ
235 * @param[in] ha ホストアダプタNo
236 * @param[in] tg ターゲットID
237 * @param[in] timeout タイムアウト(秒)
238 * @retval RET_OK 成功
239 * @retval RET_NG 失敗
240 */
241 int SetDriveAspiSetting(CMDDRIVE *drive, int *ha, int *tg, DWORD *timeout)
242 {
243 drive->cmd_type = CMDDRVCTYPE_UNKNOWN;
244 return SetAspiSetting(&drive->u.drive, ha, tg, timeout);
245 }
246
247 /**
248 * @brief ドライブが使用する転送用バッファを設定する
249 * @param[in] drive ドライブ
250 * @param[in] data_buf データバッファ
251 * @param[in] bufsize バッファサイズ
252 */
253 void SetDriveBuffer(CMDDRIVE *drive, BYTE *data_buf, int bufsize)
254 {
255 drive->data_buf = data_buf;
256 drive->bufsize = bufsize;
257 }
258
259 /**
260 * @brief 装置をオープンする
261 * @param[out] drive 装置構造体
262 * @param[in] id 装置ID
263 * @param[in] reader 読取装置かどうか(読取装置=TRUE)
264 * @param[in] bWaitDisc ディスク準備待ち有無(有=TRUE)
265 * @param[in] data_buf データバッファ
266 * @param[in] bufsize データバッファサイズ
267 * @retval RET_OK 正常終了
268 * @retval RET_NG エラー
269 */
270 int OpenDevice(CMDDRIVE *drive, int hid, int tid,
271 BOOL reader, BOOL bWaitDisc,
272 BYTE *data_buf, int bufsize)
273 {
274 int ret;
275 DWORD timeout=5*60;
276
277 ret = InitializeCmdDrive(drive, 0, 50, CMDDRVTYPE_DRIVE);
278 if(ret!=RET_OK){
279 return ret;
280 }
281 SetDriveBuffer(drive, data_buf, bufsize);
282 ret = SetDriveAspiSetting(drive, &hid, &tid, &timeout);
283 if(ret!=RET_OK){
284 FreeCmdDrive(drive);
285 return ret;
286 }
287
288 ret = GetDiscType(drive, &drive->disc_type, bWaitDisc);
289 if(ret!=RET_OK){
290 if(ret!=RET_ABORT && bWaitDisc){
291 UIDispMessage(MSG_CANT_GET_DISC_TYPE, UIDMT_ERROR);
292 }
293 FreeCmdDrive(drive);
294 return ret;
295 }
296 ret = SendPreventAllow(drive, 1);
297 if(ret!=RET_OK){
298 DispCommandError(drive);
299 FreeCmdDrive(drive);
300 return ret;
301 }
302
303 UIDispInfo("");
304 return RET_OK;
305 }
306
307 /**
308 * @brief オープンされた装置をクローズする
309 * @param[in] drive クローズする装置構造体
310 */
311 void CloseDevice(CMDDRIVE *drive)
312 {
313 if(drive->type == CMDDRVTYPE_DRIVE){
314 SendPreventAllow(drive, 0);
315 }
316
317 FreeCmdDrive(drive);
318 }
319
320 /**
321 * @brief 一時ファイル装置をオープン
322 * @param[in] drive 装置構造体
323 * @param[in] reader 読取装置かどうか(読取装置=TRUE)
324 * @param[in] data_buf データバッファ
325 * @param[in] bufsize データバッファサイズ
326 * @param[in] tmpfile 一時ファイルパス
327 * @retval RET_OK 正常終了
328 * @retval RET_NG エラー
329 */
330 int OpenTempImageDevice(CMDDRIVE *drive, BOOL reader,
331 BYTE *data_buf, int bufsize, const char *tmpfile)
332 {
333 int ret;
334
335 ret = InitializeCmdDrive(drive, 0, 50, CMDDRVTYPE_IMAGE);
336 if(ret!=RET_OK){
337 return ret;
338 }
339 SetDriveBuffer(drive, data_buf, bufsize);
340 ret = OpenImage(&drive->u.image, tmpfile, reader);
341 if(ret!=RET_OK){
342 FreeCmdDrive(drive);
343 return ret;
344 }
345
346 return RET_OK;
347 }
348
349 /**
350 * @brief mkisofs装置をオープン
351 * @param[in] drive 装置構造体
352 * @param[in] data_buf データバッファ
353 * @param[in] bufsize データバッファサイズ
354 * @retval RET_OK 正常終了
355 * @retval RET_NG エラー
356 */
357 int OpenMkisofsDevice(CMDDRIVE *drive, BYTE *data_buf, int bufsize)
358 {
359 #if defined(linux) || defined(WIN32)
360 char folder[_MAX_PATH];
361 int ret;
362
363 ret = UIFolderDialog(folder, sizeof(folder));
364 if(ret != UIDMRET_OK){
365 return RET_ABORT;
366 }
367 ret = InitializeCmdDrive(drive, 0, 50, CMDDRVTYPE_MKISOFS);
368 if(ret != RET_OK){
369 return ret;
370 }
371 SetDriveBuffer(drive, data_buf, bufsize);
372 MIFSetSrcPath(&drive->u.mkisofs, folder);
373 return RET_OK;
374 #else
375 return RET_NG;
376 #endif
377 }
378
379 /**
380 * @brief ISOイメージファイル装置をオープン
381 * @param[in] drive 装置構造体
382 * @param[in] reader 読取装置かどうか(読取装置=TRUE)
383 * @param[in] data_buf データバッファ
384 * @param[in] bufsize データバッファサイズ
385 * @retval RET_OK 正常終了
386 * @retval RET_NG エラー
387 */
388 int OpenISOImageDevice(CMDDRIVE *drive, BOOL reader,
389 BYTE *data_buf, int bufsize)
390 {
391 char tmpfile[_MAX_PATH];
392 int ret;
393
394 if(reader){
395 tmpfile[0] = '\0';
396 }
397 else{
398 strcpy(tmpfile, "image.iso");
399 }
400
401 ret = UIFileDialog(reader, tmpfile, sizeof(tmpfile), "iso");
402 if(ret!=UIDMRET_OK){
403 return RET_ABORT;
404 }
405 ret = InitializeCmdDrive(drive, 0, 50, CMDDRVTYPE_ISO);
406 if(ret!=RET_OK){
407 return ret;
408 }
409 SetDriveBuffer(drive, data_buf, bufsize);
410 ret = OpenImage(&drive->u.image, tmpfile, reader);
411 if(ret!=RET_OK){
412 FreeCmdDrive(drive);
413 return ret;
414 }
415
416 return RET_OK;
417 }
418
419
420
421 /**
422 * @brief オリジナルイメージファイル装置をオープン
423 * @param[in] drive 装置構造体
424 * @param[in] reader 読取装置かどうか(読取装置=TRUE)
425 * @param[in] data_buf データバッファ
426 * @param[in] bufsize データバッファサイズ
427 * @retval RET_OK 正常終了
428 * @retval RET_NG エラー
429 */
430 int OpenEnbanImageDevice(CMDDRIVE *drive, BOOL reader,
431 BYTE *data_buf, int bufsize)
432 {
433 char tmpfile[_MAX_PATH];
434 int ret;
435
436 if(reader){
437 tmpfile[0] = '\0';
438 }
439 else{
440 strcpy(tmpfile, "image.emg");
441 }
442
443 ret = UIFileDialog(reader, tmpfile, sizeof(tmpfile), "emg");
444 if(ret!=UIDMRET_OK){
445 return RET_ABORT;
446 }
447 ret = InitializeCmdDrive(drive, 0, 50, CMDDRVTYPE_IMAGE);
448 if(ret!=RET_OK){
449 return ret;
450 }
451 SetDriveBuffer(drive, data_buf, bufsize);
452 ret = OpenImage(&drive->u.image, tmpfile, reader);
453 if(ret!=RET_OK){
454 FreeCmdDrive(drive);
455 return ret;
456 }
457
458 return RET_OK;
459 }
460
461
462 /**
463 * @brief ネットワーク装置をオープン
464 * @param[in] drive 装置構造体
465 * @param[in] server 読取装置(server側)かどうか(読取装置=TRUE)
466 * @param[in] data_buf データバッファ
467 * @param[in] bufsize データバッファサイズ
468 * @retval RET_OK 正常終了
469 * @retval RET_NG エラー
470 */
471 int OpenNetDevice(CMDDRIVE *drive, BOOL server,
472 BYTE *data_buf, int bufsize)
473 {
474 int ret;
475 char remote_host[128];
476 int port_number;
477
478 ret = UINetDialog(server, remote_host, sizeof(remote_host), &port_number);
479 if(ret!=UIDMRET_OK){
480 return RET_ABORT;
481 }
482 ret = InitializeCmdDrive(drive, 0, 50, CMDDRVTYPE_NET);
483 if(ret!=RET_OK){
484 return ret;
485 }
486 SetDriveBuffer(drive, data_buf, bufsize);
487 if(server){
488 /* サーバモード */
489 drive->u.net.u.server.port = (WORD)port_number;
490 ret = NACreateServer(&drive->u.net);
491 if(ret!=RET_OK){
492 DispSocketError(&drive->u.net, ret);
493 return ret;
494 }
495 UIClearAbort();
496 while(1){
497 if(UICheckAbort()){
498 ret = RET_ABORT;
499 break;
500 }
501 ret = NAWaitConnect(&drive->u.net, 1000);
502 if(ret==RET_OK){
503 break;
504 }
505 if(ret!=RET_TIMEOUT){
506 break;
507 }
508 }
509 if(ret!=RET_OK){
510 DispSocketError(&drive->u.net, ret);
511 FreeCmdDrive(drive);
512 return ret;
513 }
514 }
515 else{
516 /* クライアントモード */
517 drive->u.net.remote_host = MemNew(strlen(remote_host)+1);
518 strncpy(drive->u.net.remote_host, remote_host, strlen(remote_host)+1);
519 drive->u.net.u.client.remote_port = (WORD)port_number;
520 ret = NAConnect(&drive->u.net);
521 if(ret!=RET_OK){
522 DispSocketError(&drive->u.net, ret);
523 FreeCmdDrive(drive);
524 return ret;
525 }
526
527 ret = GetDiscType(drive, &drive->disc_type, TRUE);
528 if(ret!=RET_OK){
529 if(ret!=RET_ABORT){
530 UIDispMessage(MSG_CANT_GET_DISC_TYPE
531 /*"ディスクタイプ取得に失敗しました。"*/, UIDMT_ERROR);
532 }
533 FreeCmdDrive(drive);
534 return ret;
535 }
536 ret = SendPreventAllow(drive, 1);
537 if(ret!=RET_OK){
538 DispCommandError(drive);
539 FreeCmdDrive(drive);
540 return ret;
541 }
542 }
543
544 return RET_OK;
545 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26