#include #include "kernelmisc.h" #include "debug.h" #include "deviceinfo.h" #include "FileFunctions.h" #include // todo: make flush threshold + buffer parms configurable via commandline bool savechunk(HANDLE h, BYTE *start, DWORD prev, DWORD cur, DWORD end) { DWORD wrote; if (prev < cur) { //debug("%08lx: %08lx < %08lx %08lx\n", start, prev, cur, end); if (!WriteFile(h, start+prev, cur-prev, &wrote, 0)) { error("WriteFile"); return false; } } if (cur <= prev) { //debug("%08lx: %08lx > %08lx %08lx\n", start, prev, cur, end); if (prev!=cur && !WriteFile(h, start+prev, end-prev, &wrote, 0)) { error("WriteFile"); return false; } if (!WriteFile(h, start, cur, &wrote, 0)) { error("WriteFile"); return false; } } if (!FlushFileBuffers(h)) error("FlushFileBuffers"); return true; } bool timetosave(DWORD prev, DWORD cur, DWORD end) { if (prev 0x1000) return true; if (cur 0x1000) return true; return false; } HANDLE newlog() { SYSTEMTIME now; GetLocalTime(&now); std::string dbglogname= stringformat("dbg-%02d%02d%02d-%02d%02d%02d.log", now.wYear, now.wMonth, now.wDay, now.wHour, now.wMinute, now.wSecond); HANDLE h= CreateFile(ToTString(dbglogname).c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (h==INVALID_HANDLE_VALUE) { error("CreateFile"); return 0; } return h; } bool dontrecurse(const std::string& path) { return false; } struct listbuilder { StringList &l; std::string basename; std::string filename; listbuilder(StringList &l, const std::string& basename, const std::string& filename) : l(l), basename(basename), filename(filename) { std::replace(this->basename.begin(), this->basename.end(), '\\', '/'); } void operator()(const std::string& path) { if (path.size()>basename.size()+filename.size()) if (path.substr(0, basename.size()) == basename && path.substr(path.size()-filename.size()) == filename) l.push_back(path); } }; void DeleteOldLogs() { StringList logfiles; dir_iterator("/", listbuilder(logfiles, "/dbg-", ".log"), dontrecurse); std::sort(logfiles.begin(), logfiles.end()); if (logfiles.empty()) return; DeleteFile(logfiles[0]); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("dbglog.log"); KernelMode _km; deviceinfo di; DWORD base; DWORD bufsize; DWORD curptr; if (!di.GetKernelLogBuf(base, bufsize, curptr)) { debug("unknown device: %d\n", di.devtype()); return 0; } debug("params: base=%08lx, size=%08lx, ptr=%08lx\n", base, bufsize, curptr); BYTE *buffer= (BYTE*)base; volatile DWORD &curpos= *(volatile DWORD*)curptr; HANDLE h= newlog(); if (!h) return 1; DWORD bytessaved= 0; DWORD prevpos= curpos; if (!savechunk(h, buffer, prevpos, prevpos, bufsize)) { CloseHandle(h); return 1; } bytessaved += bufsize; while (1) { Sleep(10); DWORD pos= curpos; if (timetosave(prevpos, pos, bufsize)) { savechunk(h, buffer, prevpos, pos, bufsize); bytessaved += prevpos 0x1000000) { uint64_t freespace= GetFilesystemFreeSpace("/"); debug("disk: bytessaved=%d free= %lld\n", bytessaved, freespace); CloseHandle(h); bytessaved= 0; h= newlog(); if (freespace < 0x1000000) { DeleteOldLogs(); } } } } return 0; }