| 1 |
/** |
| 2 |
* @file cmdlog.c |
| 3 |
* @brief コマンドログ |
| 4 |
* @author BananaJinn |
| 5 |
* @version $Id: cmdlog.c,v 1.19 2010/01/17 09:26:24 bananajinn Exp $ |
| 6 |
* 円盤複写屋 |
| 7 |
* Copyright (C) 2004-2006 BananaJinn<banana@mxh.mesh.ne.jp>. |
| 8 |
*/ |
| 9 |
|
| 10 |
#include <stdio.h> |
| 11 |
#include <string.h> |
| 12 |
#include <stdlib.h> |
| 13 |
#include <sys/types.h> |
| 14 |
#if defined(_WIN32) |
| 15 |
# include <windows.h> |
| 16 |
#else |
| 17 |
# include <pwd.h> |
| 18 |
# include <unistd.h> |
| 19 |
#endif |
| 20 |
#include "mem.h" |
| 21 |
#include "aspi.h" |
| 22 |
#include "cmd.h" |
| 23 |
#include "cmdlog.h" |
| 24 |
#include "text.h" |
| 25 |
#include "ui.h" |
| 26 |
#include "ebstring.h" |
| 27 |
|
| 28 |
#define CMDLOGFILE 0 |
| 29 |
|
| 30 |
int |
| 31 |
CreateLog(CMDDRIVE *pReader, CMDDRIVE *pWriter, int nWriter) |
| 32 |
{ |
| 33 |
int ret; |
| 34 |
const BYTE inqcmd[12]={CMD_INQUIRY, 0, 0, 0, 96, 0, 0, 0, 0, 0, 0, 0}; |
| 35 |
char path[_MAX_PATH]; |
| 36 |
#if defined(_WIN32) |
| 37 |
char *fname = "\\EnbanLog.txt"; |
| 38 |
#else |
| 39 |
char *fname = "/EnbanLog.txt"; |
| 40 |
#endif |
| 41 |
FILE *fp; |
| 42 |
int nDrive, nCount, nPos; |
| 43 |
DWORD nDumpPos, nDataLen; |
| 44 |
CMDDRIVE *pDrive; |
| 45 |
#if defined(_WIN32) |
| 46 |
GetCurrentDirectory(sizeof(path), path); |
| 47 |
#else |
| 48 |
struct passwd *pwent; |
| 49 |
|
| 50 |
pwent = getpwuid(getuid()); |
| 51 |
strncpy(path, pwent->pw_dir, sizeof(path)); |
| 52 |
#endif |
| 53 |
if(strlen(path)+strlen(fname)+1 >= _MAX_PATH){ |
| 54 |
return RET_NG; |
| 55 |
} |
| 56 |
strcat(path, fname); |
| 57 |
|
| 58 |
fp = fopen(path, "w"); |
| 59 |
if(fp==NULL){ |
| 60 |
return RET_NG; |
| 61 |
} |
| 62 |
|
| 63 |
for(nDrive=0; nDrive<1+nWriter; nDrive++){ |
| 64 |
if(nDrive==0){ |
| 65 |
if(!REALDRIVE(pReader)){ |
| 66 |
continue; |
| 67 |
} |
| 68 |
fprintf(fp, MSG_READER_ /*"読込装置 : "*/); |
| 69 |
pDrive = pReader; |
| 70 |
} |
| 71 |
else{ |
| 72 |
if(!REALDRIVE(&pWriter[nDrive-1])){ |
| 73 |
continue; |
| 74 |
} |
| 75 |
fprintf(fp, MSG_WRITER_ /*"書込装置%d : "*/, nDrive); |
| 76 |
pDrive = &pWriter[nDrive-1]; |
| 77 |
} |
| 78 |
|
| 79 |
ret = SendCmd(pDrive, (BYTE *)inqcmd, 96, REQ_DATAIN); |
| 80 |
if(ret!=RET_OK){ |
| 81 |
fputs("\n", fp); |
| 82 |
} |
| 83 |
else{ |
| 84 |
pDrive->data_buf[8+40] = '\0'; |
| 85 |
fprintf(fp, "%s\n", pDrive->data_buf+8); |
| 86 |
} |
| 87 |
|
| 88 |
if(pDrive->cmdlog==NULL) |
| 89 |
continue; |
| 90 |
|
| 91 |
for(nPos=pDrive->cmdlog_start; ; nPos++){ |
| 92 |
if(nPos >= pDrive->cmdlog_size) |
| 93 |
nPos=0; |
| 94 |
fprintf(fp, "[%02d]", nPos); |
| 95 |
fputs("CDB=", fp); |
| 96 |
for(nCount=0; nCount<12; nCount++){ |
| 97 |
fprintf(fp, "%02X ", pDrive->cmdlog[nPos].cdb[nCount]); |
| 98 |
} |
| 99 |
fprintf(fp, ": %X/%02X/%02X", |
| 100 |
pDrive->cmdlog[nPos].snskey, |
| 101 |
pDrive->cmdlog[nPos].asc, |
| 102 |
pDrive->cmdlog[nPos].ascq); |
| 103 |
if(pDrive->cmdlog[nPos].repeat>1){ |
| 104 |
fprintf(fp, " : repeat %d times", pDrive->cmdlog[nPos].repeat); |
| 105 |
} |
| 106 |
fputs("\n", fp); |
| 107 |
if(pDrive->cmdlog[nPos].datalen>0 && pDrive->cmdlog[nPos].reqflag!=REQ_NODATA && |
| 108 |
pDrive->cmdlog[nPos].data!=NULL){ |
| 109 |
fprintf(fp, " DATA%s %ldbyte(s)\n", |
| 110 |
pDrive->cmdlog[nPos].reqflag==REQ_DATAIN ? "IN" : "OUT", |
| 111 |
(long)pDrive->cmdlog[nPos].datalen); |
| 112 |
nDataLen = pDrive->cmdlog[nPos].datalen; |
| 113 |
if(nDataLen > pDrive->cmdlog_maxdatalen) |
| 114 |
nDataLen = pDrive->cmdlog_maxdatalen; |
| 115 |
for(nDumpPos=0; nDumpPos<nDataLen; nDumpPos++){ |
| 116 |
if((nDumpPos % 16)==0) |
| 117 |
fputs(" ", fp); |
| 118 |
fprintf(fp, " %02X", pDrive->cmdlog[nPos].data[nDumpPos]); |
| 119 |
if((nDumpPos % 16)==15) |
| 120 |
fputs("\n", fp); |
| 121 |
} |
| 122 |
if((nDumpPos % 16)!=0) |
| 123 |
fputs("\n", fp); |
| 124 |
} |
| 125 |
if(nPos==pDrive->cmdlog_end) |
| 126 |
break; |
| 127 |
} |
| 128 |
} |
| 129 |
fclose(fp); |
| 130 |
|
| 131 |
{ |
| 132 |
char *message = EbStringNewWithFormat(MSG_CMDLOG_WAS_SAVED_TO_, path); |
| 133 |
UIDispMessage(message, UIDMT_INFORMATION); |
| 134 |
EbStringFree(message); |
| 135 |
} |
| 136 |
|
| 137 |
return RET_OK; |
| 138 |
} |
| 139 |
|
| 140 |
|
| 141 |
void |
| 142 |
CmdLog(CMDDRIVE *drive, BYTE *cdb, DWORD buflen, BYTE reqflag, |
| 143 |
int retcode) |
| 144 |
{ |
| 145 |
CMDLOG *cmdlog; |
| 146 |
int repeat_flag=0; |
| 147 |
|
| 148 |
#if CMDLOGFILE |
| 149 |
{ |
| 150 |
int i; |
| 151 |
DWORD len; |
| 152 |
FILE *fp; |
| 153 |
fp=fopen("cmdlog.txt", "a"); |
| 154 |
if(fp!=NULL){ |
| 155 |
fprintf(fp, "[%d:%d]", drive->hid, drive->tid); |
| 156 |
for(i=0; i<12; i++){ |
| 157 |
fprintf(fp, " %02X", cdb[i]); |
| 158 |
} |
| 159 |
fprintf(fp, " : status=%x:%02x:%02x\n", |
| 160 |
drive->sense_data[2], |
| 161 |
drive->sense_data[12], |
| 162 |
drive->sense_data[13]); |
| 163 |
if(reqflag==REQ_DATAOUT || reqflag==REQ_DATAIN){ |
| 164 |
fprintf(fp, " %s(%ld):", reqflag==REQ_DATAOUT ? "DATAOUT":"DATAIN", buflen); |
| 165 |
len = buflen < 64 ? buflen : 64; |
| 166 |
for(i=0; i<len; i++){ |
| 167 |
if((i%16)==0) |
| 168 |
fputs(" ", fp); |
| 169 |
fprintf(fp, " %02X", drive->data_buf[i]); |
| 170 |
if((i%16)==15) |
| 171 |
fputs("\n", fp); |
| 172 |
} |
| 173 |
if((i%16)!=0) |
| 174 |
fputs("\n", fp); |
| 175 |
} |
| 176 |
fclose(fp); |
| 177 |
} |
| 178 |
} |
| 179 |
#endif |
| 180 |
if(drive->cmdlog!=NULL){ |
| 181 |
if(drive->cmdlog_end<0){ |
| 182 |
drive->cmdlog_end++; |
| 183 |
} |
| 184 |
else{ |
| 185 |
cmdlog = &drive->cmdlog[drive->cmdlog_end]; |
| 186 |
if(memcmp(cmdlog->cdb, cdb, 12)==0 && |
| 187 |
cmdlog->snskey == drive->sense_data[2] && |
| 188 |
cmdlog->asc == drive->sense_data[12] && |
| 189 |
cmdlog->ascq == drive->sense_data[13]){ |
| 190 |
if(drive->cmdlog[drive->cmdlog_end].repeat < 65535) |
| 191 |
drive->cmdlog[drive->cmdlog_end].repeat++; |
| 192 |
repeat_flag = 1; |
| 193 |
} |
| 194 |
else{ |
| 195 |
drive->cmdlog_end = (drive->cmdlog_end+1) % drive->cmdlog_size; |
| 196 |
if(drive->cmdlog_end==drive->cmdlog_start){ |
| 197 |
drive->cmdlog_start = (drive->cmdlog_start+1) % drive->cmdlog_size; |
| 198 |
} |
| 199 |
} |
| 200 |
} |
| 201 |
|
| 202 |
if(!repeat_flag){ |
| 203 |
cmdlog = &drive->cmdlog[drive->cmdlog_end]; |
| 204 |
memcpy(cmdlog->cdb, cdb, 12); |
| 205 |
cmdlog->reqflag = reqflag; |
| 206 |
cmdlog->datalen = buflen; |
| 207 |
MemFree(cmdlog->data); |
| 208 |
cmdlog->data = NULL; |
| 209 |
if(cdb[0]!=CMD_WRITE10 && |
| 210 |
cdb[0]!=CMD_WRITE12 && |
| 211 |
cdb[0]!=CMD_WRITE_AND_VERIFY && |
| 212 |
cdb[0]!=CMD_READ6 && |
| 213 |
cdb[0]!=CMD_READ10 && |
| 214 |
cdb[0]!=CMD_READ12 && |
| 215 |
cdb[0]!=CMD_READ_CD && |
| 216 |
cdb[0]!=CMD_READ_CD_DA){ |
| 217 |
if(buflen>0 && |
| 218 |
(reqflag==REQ_DATAOUT || |
| 219 |
(reqflag==REQ_DATAIN && retcode==RET_OK))){ |
| 220 |
if(buflen > drive->cmdlog_maxdatalen) |
| 221 |
buflen = drive->cmdlog_maxdatalen; |
| 222 |
if(cmdlog->data!=NULL) |
| 223 |
MemFree(cmdlog->data); |
| 224 |
cmdlog->data = MemNew(buflen); |
| 225 |
memcpy(cmdlog->data, drive->data_buf, buflen); |
| 226 |
} |
| 227 |
else{ |
| 228 |
if(cmdlog->data!=NULL){ |
| 229 |
MemFree(cmdlog->data); |
| 230 |
cmdlog->data = NULL; |
| 231 |
} |
| 232 |
} |
| 233 |
} |
| 234 |
cmdlog->snskey = drive->sense_data[2] & 0x0f; |
| 235 |
cmdlog->asc = drive->sense_data[12]; |
| 236 |
cmdlog->ascq = drive->sense_data[13]; |
| 237 |
cmdlog->repeat = 1; |
| 238 |
} |
| 239 |
} |
| 240 |
} |
| 241 |
|
| 242 |
|
| 243 |
int CmdLogInit(CMDDRIVE *drive, int cmdlog_size) |
| 244 |
{ |
| 245 |
CmdLogFree(drive); |
| 246 |
|
| 247 |
if(cmdlog_size>0){ |
| 248 |
drive->cmdlog = (CMDLOG *)MemNew(sizeof(CMDLOG)*cmdlog_size); |
| 249 |
if(drive->cmdlog==NULL){ |
| 250 |
return RET_NG; |
| 251 |
|
| 252 |
} |
| 253 |
memset(drive->cmdlog, 0, sizeof(CMDLOG)*cmdlog_size); |
| 254 |
drive->cmdlog_size = cmdlog_size; |
| 255 |
drive->cmdlog_start = 0; |
| 256 |
drive->cmdlog_end = -1; |
| 257 |
drive->cmdlog_maxdatalen = 0x200; |
| 258 |
} |
| 259 |
|
| 260 |
return RET_OK; |
| 261 |
} |
| 262 |
|
| 263 |
void CmdLogFree(CMDDRIVE *drive) |
| 264 |
{ |
| 265 |
int i; |
| 266 |
|
| 267 |
if(drive->cmdlog!=NULL){ |
| 268 |
for(i=0; i<drive->cmdlog_size; i++){ |
| 269 |
if(drive->cmdlog[i].data!=NULL) |
| 270 |
MemFree(drive->cmdlog[i].data); |
| 271 |
} |
| 272 |
MemFree(drive->cmdlog); |
| 273 |
drive->cmdlog = NULL; |
| 274 |
} |
| 275 |
} |
| 276 |
|