⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 logscsi.cpp

📁 DVD工具dvdsynth的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
   int len = min(available_length, actual_length);
   for (int i=0; i<len; ++i) {
      wsprintf(buf + i*3, "%02X ", bytes[i]);
   }
   if (actual_length <= available_length) {
      buf[len*3-1] = 0;
   } else {
      wsprintf(buf + len*3 - 1, "... (%d bytes)", actual_length);
   }
   return buf;
}


const char* GetItemText(LogScsiUser* that, int row, int col) {
   if (row == LogScsiUser::max_scis - 1) {
      switch (col) {
      case 1: return "[Log buffer full]";
      case 2: return "[Clear it to continue logging]";
      default: return 0;
      }
   }
   static char buf[128];
   SavedCommandInfo sci = that->scis[row];
   switch (col) {
   case 0:  // command
      if (sci.cdb[0] <= 0x5D) {
         return scsi_command_names_00_5D[sci.cdb[0]];
      } else if (sci.cdb[0] >= 0xA0 && sci.cdb[0] <= 0xBF) {
         return scsi_command_names_A0_BF[sci.cdb[0]-0xA0];
      } else {
         return undefined;
      }
   case 1:  // CDB
      return HexByteString(sci.cdb, 12, sci.cdb_size+1);
   case 2:  // Result
      {
         if (sci.result == SCSIRESULT_SUCCESS) {
            return "success";
         }
         unsigned char srb_stat = SCSIRESULT_SRBSTAT(sci.result);
         unsigned char targ_stat = SCSIRESULT_TARGSTAT(sci.result);
         unsigned char sense_key = SCSIRESULT_SENSEKEY(sci.result);
         unsigned char asc = SCSIRESULT_ASC(sci.result);
         unsigned char ascq = SCSIRESULT_ASCQ(sci.result);
         if (srb_stat != SRB_STATUS_SUCCESS && srb_stat != SRB_STATUS_ERROR) {
            if (srb_stat <= 0x24 && srb_status_names[srb_stat] != 0) {
               strcpy(buf, srb_status_names[srb_stat]);
            } else {
               wsprintf(buf, "%02X", srb_stat);
            }
            wsprintf(buf+strlen(buf), " (%02X %X %02X %02X)", targ_stat, sense_key, asc, ascq);
            return buf;
         }
         buf[0] = 0;
         if (srb_stat != SRB_STATUS_ERROR || targ_stat != SCSISTAT_CHECK_CONDITION) {
            if (targ_stat <= 0x28 && target_status_names[targ_stat>>1] != 0) {
               wsprintf(buf, "%s/%s/", srb_status_names[srb_stat], target_status_names[targ_stat>>1]);
            } else {
               wsprintf(buf, "%s/%02X/", srb_status_names[srb_stat], targ_stat);
            }
         }
         // note: depends on format of scsi_result_t
         for (int i=0; i<sizeof(result_code_names)/sizeof(result_code_names[0]); ++i) {
            if (result_code_names[i].result == SCSIRESULT_SENSE(sci.result)) {
               strcat(buf, result_code_names[i].text);
               return buf;
            }
         }
         wsprintf(buf+strlen(buf), "%s (%02X %02X)", sense_key_names[sense_key], asc, ascq);
         return buf;
      }
   case 3:  // Data out
      if ((sci.inout & 2) && sci.buffer_size != 0) {
         return HexByteString(sci.buffer, 12, sci.buffer_size);
      } else {
         return "";
      }
   case 4:  // Data in
      if ((sci.inout & 1) && sci.buffer_size != 0) {
         return HexByteString(sci.buffer, 12, sci.buffer_size);
      } else {
         return "";
      }
   default:
      return "???";
   }
}


void SaveLog(HWND hwndOwner, LogScsiUser* u) {
   static char filename[MAX_PATH];
   OPENFILENAME ofn;
   ofn.lStructSize = 76;
   ofn.hwndOwner = hwndOwner;
   ofn.hInstance = g_hinstance;
   ofn.lpstrFilter = "Comma-delimited text file (*.csv)\0*.csv\0";
   ofn.lpstrCustomFilter = NULL;
   ofn.nMaxCustFilter = 0;
   ofn.nFilterIndex = 2;
   ofn.lpstrFile = filename;
   ofn.nMaxFile = MAX_PATH;
   ofn.lpstrFileTitle = NULL;
   ofn.nMaxFileTitle = 0;
   ofn.lpstrInitialDir = NULL;
   ofn.lpstrTitle = "Save SCSI log";
   ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
   ofn.lpstrDefExt = "csv";
   ofn.lpfnHook = NULL;
   ofn.lpTemplateName = NULL;
   if (GetSaveFileName(&ofn)) {
      FILE* out = fopen(filename, "wb");
      if (out) {
         for (int row = 0; row < u->num_scis; ++row) {
            for (int col = 0; col < 5; ++col) {
               if (col != 0)
                  putc(',', out);
               const char* text = GetItemText(u, row, col);
               if (text) {
                  const char* comma = strchr(text, ',');
                  if (comma)
                     putc('"', out);
                  fputs(text, out);
                  if (comma)
                     putc('"', out);
               }
            }
            putc('\n', out);
         }
         fclose(out);
      } else {
         MessageBox(hwndOwner, "Could not open the file for writing.", "SCSI logger", MB_OK);
      }
   }
}


class LogCommandsListView : public ListView {
   LogScsiUser* that;
public:
   LogCommandsListView(NestableWindow* parent, LogScsiUser* _that) : ListView(parent), that(_that) {}
   const char* GetItemText(int row, int col) { return ::GetItemText(that, row, col); }
};


class LogCommandsFrameWindow : public FrameWindow {
   HMENU hmenu;
   LogScsiUser* that;
public:
   bool hidden;
   LogCommandsFrameWindow(const char* name, LogScsiUser* _that)
     : FrameWindow(name, hmenu = LoadMenu(g_hinstance, MAKEINTRESOURCE(IDR_LOGCOMMANDS))),
       that(_that)
   {
      hidden = false;
   }
   bool OnClose() {
      Hide();
      hidden = true;
      return true;
   }
   bool OnMenuCommand(int id, bool is_accelerator) {
      static MENUITEMINFO mii = { 48, MIIM_TYPE, MFT_STRING };
      switch (id) {
      case ID_STARTSTOP:
         that->k->log = !that->k->log;
         mii.dwTypeData = (char*)(that->k->log ? "&Stop!" : "&Start!");
         SetMenuItemInfo(hmenu, id, FALSE, &mii);
         DrawMenuBar(hwnd);
         return true;
      case ID_CLEAR:
         that->num_scis = 0;
         that->listview->SetNumItems(0);
         return true;
      case ID_FILE_SAVEAS:
         SaveLog(hwnd, that);
         return true;
      case ID_OPTIONS_IGNORETESTUNITREADY:
         that->k->ignore_testunitready = !that->k->ignore_testunitready;
         CheckMenuItem(hmenu, id, that->k->ignore_testunitready ? MF_CHECKED : MF_UNCHECKED);
         return true;
      default:
         return false;
      }
   }
};


unsigned __stdcall ThreadProc(void* param) {
   LogScsiUser* u = (LogScsiUser*)param;
   LogScsiKernel* k = u->k;
   for (;;) {
      WaitForSingleObject(u->event, INFINITE);
      if (u->quit)
         break;
      unsigned h = k->head, t = k->tail;
      if (t < h) {
         do {
            if (u->num_scis < u->max_scis) {
               u->scis[u->num_scis++] = k->scis[t % k->queue_size];
               u->listview->AddItem(true);
            }
            ++t;
         } while (t < h);
         k->tail = t;
      }
   }
   return 0;
}


void LogScsiUser_ShowHide(void* self, int) {
   LogScsiUser* u = (LogScsiUser*) self;
   u->frame->hidden = !u->frame->hidden;
   if (u->frame->hidden)
      u->frame->Hide();
   else
      u->frame->Show();
}


void LogScsiUser_AddDeviceMenuItems(DvsDeviceUser* self, DvsMenu* menu) {
   LogScsiUser* u = (LogScsiUser*) self;
   menu->vtable->AddItem(menu, "Show SCSI log", !u->frame->hidden, LogScsiUser_ShowHide, u, 0);
}


void LogScsiUser_Delete(DvsDeviceUser* self) {
   LogScsiUser* u = (LogScsiUser*) self;
   g_callbacks->Driver_Unload(u->driver_handle);
   u->quit = true;
   SetEvent(u->event);
   WaitForSingleObject(u->hthread, INFINITE);
   CloseHandle(u->hthread);
   g_callbacks->CloseKernelEventHandle(u->k->event);
   CloseHandle(u->event);
   delete u->frame;
   delete u->listview;
   delete u;
}


DvsDeviceUser_vtable logscsiuser_vtable = {
   LogScsiUser_AddDeviceMenuItems,
   0, // queryunplug
   LogScsiUser_Delete
};


DvsDeviceUser* HookDevice(DvsDeviceKernel** pkernel, DvsDockingBay* bay) {
   LogScsiUser* u = new LogScsiUser;
   u->vtable = &logscsiuser_vtable;
   u->name = "SCSI log";
   u->frame = new LogCommandsFrameWindow(u->name, u);
   u->listview = new LogCommandsListView(u->frame, u);
   u->listview->InsertColumn(0, 100, "Command", 0);
   u->listview->InsertColumn(1, 200, "CDB", 0);
   u->listview->InsertColumn(2, 120, "Result", 0);
   u->listview->InsertColumn(3, 100, "Data out", 0);
   u->listview->InsertColumn(4, 100, "Data in", 0);
   u->frame->SetChild(u->listview);
   u->event = CreateEvent(NULL, FALSE, FALSE, NULL);
   u->quit = false;
   u->num_scis = 0;

   u->driver_handle = g_callbacks->Driver_Load("LogScsi.kll");

   u->k = (LogScsiKernel*)bay->vtable->SharedPool_Alloc(bay, sizeof(LogScsiKernel));
   u->k->ScsiCommand = (dvs_scsi_func*)g_callbacks->Driver_Call(u->driver_handle, "GetDispatchFunc", "");
   u->k->child = *pkernel;
   u->k->event = g_callbacks->OpenKernelEventHandle(u->event);
   u->k->log = true;
   u->k->ignore_testunitready = true;
   u->k->head = 0;
   u->k->tail = 0;

   unsigned thread_id;
   u->hthread = (HANDLE)_beginthreadex(NULL, 0, ThreadProc, u, 0, &thread_id);

   *pkernel = u->k;
   return u;
}


DvsFilterGlobal plugin_info = {
	0,
	"SCSI protocol spy",
	DVDSYNTH_FILTER_ALL_DEVICE_CLASSES,
	HookDevice,
	0
};


extern "C"
DvsFilterGlobal* DvdsynthFilterPluginEntry(DvsDockingBayGlobal* callbacks) {
	g_callbacks = callbacks;
	return &plugin_info;
}

extern "C"
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID) {
	g_hinstance = hinst;
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -