Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

393 lines
12 KiB

  1. /*
  2. logger.h
  3. Use to write log info to a file.
  4. Multiple-instance aware. If one instance already owns the output
  5. file, another will sleep (up to 20s) until the first is done.
  6. Nicely outputs a header containing user, computer, and driver names,
  7. date/time and starting display resolution.
  8. You use it like this:
  9. CLogfile Log("test.log","your comment here");
  10. // or CLogfile Log("test.log");
  11. // for no comment, and overwriting the file.
  12. // or CLogfile Log("test.log","your comment here",TRUE);
  13. // to make it append to the file. Default is overwrite.
  14. Log << "\n\n42 decimal is " << 42ul <<" in hex\n";
  15. Log << "Hi"<<'!'<<'\n' ;
  16. Log << "The value of 0x2a is " << 0x2al << " in decimal\n";
  17. CLogfile Faults("faults.log","my test's faults",TRUE); //append new faults
  18. Faults << "Encountered a booboo, here's what i did:\n";
  19. Faults << Log; //copies contents of test.log to Fault
  20. Faults << "so now you can diagnose\n";
  21. The class will then write stuff like this to test.log:
  22. ----------------------------------------------------------
  23. EnumSurface test
  24. Beginning test at 10:38 on 1995/8/14
  25. User Name:jeffno
  26. Computer Name:JEFFNO2
  27. Display driver:S3 Vision864 PCI
  28. Starting resolution: 640x480x8
  29. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  30. 42 decimal is 0000002a in hex
  31. Hi!
  32. The value of 0x2a is 42 in decimal
  33. ----------- Test ends at 10:38 on 1995/8/14 -------------
  34. And faults.log will get:
  35. < a header like above>
  36. Encountered a booboo, here's what i did:
  37. < a copy of the test.log contents surrounded by
  38. notes that say this is a snapshot of test.log >
  39. so now you can diagnose
  40. < a trailer like above (test ends at etc...)>
  41. The class can output DWORDS, which it does as an 8-digit hex number,
  42. LONGs which are output as decimal, chars and strings. As shown
  43. above you can output one log object to another, which copies
  44. everything in the source file from the pos at which the source
  45. file was opened (if appending to a pre-existing file) up to
  46. the end.
  47. But wait! you also get...
  48. A routine called char * ErrorName(HRESULT) which takes
  49. a ddraw return value and returns a string describing it.
  50. Very handy.
  51. BTW: this header file includes a statically declared array
  52. full of names, at file level scope. This means you get a 2k
  53. array in your source wether you want ErrorName or not.
  54. Go ahead and edit this file if you don't want this array.
  55. NOTE: this uses WNetGetUser API, so you'll need to add mpr.lib
  56. to you LIBS line in your makefile.
  57. */
  58. //#include <stdio.h>
  59. #include <windows.h>
  60. #include <windowsx.h>
  61. struct {
  62. char name[100];
  63. HRESULT errcode;
  64. } ErrorLookup[] = {
  65. {"DD_OK",DD_OK},
  66. {"DDERR_ALREADYINITIALIZED",DDERR_ALREADYINITIALIZED},
  67. {"DDERR_CANNOTATTACHSURFACE",DDERR_CANNOTATTACHSURFACE},
  68. {"DDERR_CANNOTDETACHSURFACE",DDERR_CANNOTDETACHSURFACE},
  69. {"DDERR_CURRENTLYNOTAVAIL",DDERR_CURRENTLYNOTAVAIL},
  70. {"DDERR_EXCEPTION",DDERR_EXCEPTION},
  71. {"DDERR_GENERIC",DDERR_GENERIC},
  72. {"DDERR_HEIGHTALIGN",DDERR_HEIGHTALIGN},
  73. {"DDERR_INCOMPATIBLEPRIMARY",DDERR_INCOMPATIBLEPRIMARY},
  74. {"DDERR_INVALIDCAPS",DDERR_INVALIDCAPS},
  75. {"DDERR_INVALIDCLIPLIST",DDERR_INVALIDCLIPLIST},
  76. {"DDERR_INVALIDMODE",DDERR_INVALIDMODE},
  77. {"DDERR_INVALIDOBJECT",DDERR_INVALIDOBJECT},
  78. {"DDERR_INVALIDPARAMS",DDERR_INVALIDPARAMS},
  79. {"DDERR_INVALIDPIXELFORMAT",DDERR_INVALIDPIXELFORMAT},
  80. {"DDERR_INVALIDRECT",DDERR_INVALIDRECT},
  81. {"DDERR_LOCKEDSURFACES",DDERR_LOCKEDSURFACES},
  82. {"DDERR_NO3D",DDERR_NO3D},
  83. {"DDERR_NOALPHAHW",DDERR_NOALPHAHW},
  84. {"DDERR_NOANTITEARHW",DDERR_NOANTITEARHW},
  85. {"DDERR_NOBLTQUEUEHW",DDERR_NOBLTQUEUEHW},
  86. {"DDERR_NOCLIPLIST",DDERR_NOCLIPLIST},
  87. {"DDERR_NOCOLORCONVHW",DDERR_NOCOLORCONVHW},
  88. {"DDERR_NOCOOPERATIVELEVELSET",DDERR_NOCOOPERATIVELEVELSET},
  89. {"DDERR_NOCOLORKEY",DDERR_NOCOLORKEY},
  90. {"DDERR_NOCOLORKEYHW",DDERR_NOCOLORKEYHW},
  91. {"DDERR_NOEXCLUSIVEMODE",DDERR_NOEXCLUSIVEMODE},
  92. {"DDERR_NOFLIPHW",DDERR_NOFLIPHW},
  93. {"DDERR_NOGDI",DDERR_NOGDI},
  94. {"DDERR_NOMIRRORHW",DDERR_NOMIRRORHW},
  95. {"DDERR_NOTFOUND",DDERR_NOTFOUND},
  96. {"DDERR_NOOVERLAYHW",DDERR_NOOVERLAYHW},
  97. {"DDERR_NORASTEROPHW",DDERR_NORASTEROPHW},
  98. {"DDERR_NOROTATIONHW",DDERR_NOROTATIONHW},
  99. {"DDERR_NOSTRETCHHW",DDERR_NOSTRETCHHW},
  100. {"DDERR_NOT4BITCOLOR",DDERR_NOT4BITCOLOR},
  101. {"DDERR_NOT4BITCOLORINDEX",DDERR_NOT4BITCOLORINDEX},
  102. {"DDERR_NOT8BITCOLOR",DDERR_NOT8BITCOLOR},
  103. {"DDERR_NOTEXTUREHW",DDERR_NOTEXTUREHW},
  104. {"DDERR_NOVSYNCHW",DDERR_NOVSYNCHW},
  105. {"DDERR_NOZBUFFERHW",DDERR_NOZBUFFERHW},
  106. {"DDERR_NOZOVERLAYHW",DDERR_NOZOVERLAYHW},
  107. {"DDERR_OUTOFCAPS",DDERR_OUTOFCAPS},
  108. {"DDERR_OUTOFMEMORY",DDERR_OUTOFMEMORY},
  109. {"DDERR_OUTOFVIDEOMEMORY",DDERR_OUTOFVIDEOMEMORY},
  110. {"DDERR_OVERLAYCANTCLIP",DDERR_OVERLAYCANTCLIP},
  111. {"DDERR_OVERLAYCOLORKEYONLYONEACTIVE",DDERR_OVERLAYCOLORKEYONLYONEACTIVE},
  112. {"DDERR_PALETTEBUSY",DDERR_PALETTEBUSY},
  113. {"DDERR_COLORKEYNOTSET",DDERR_COLORKEYNOTSET},
  114. {"DDERR_SURFACEALREADYATTACHED",DDERR_SURFACEALREADYATTACHED},
  115. {"DDERR_SURFACEALREADYDEPENDENT",DDERR_SURFACEALREADYDEPENDENT},
  116. {"DDERR_SURFACEBUSY",DDERR_SURFACEBUSY},
  117. {"DDERR_SURFACEISOBSCURED",DDERR_SURFACEISOBSCURED},
  118. {"DDERR_SURFACELOST",DDERR_SURFACELOST},
  119. {"DDERR_SURFACENOTATTACHED",DDERR_SURFACENOTATTACHED},
  120. {"DDERR_TOOBIGHEIGHT",DDERR_TOOBIGHEIGHT},
  121. {"DDERR_TOOBIGSIZE",DDERR_TOOBIGSIZE},
  122. {"DDERR_TOOBIGWIDTH",DDERR_TOOBIGWIDTH},
  123. {"DDERR_UNSUPPORTED",DDERR_UNSUPPORTED},
  124. {"DDERR_UNSUPPORTEDFORMAT",DDERR_UNSUPPORTEDFORMAT},
  125. {"DDERR_UNSUPPORTEDMASK",DDERR_UNSUPPORTEDMASK},
  126. {"DDERR_VERTICALBLANKINPROGRESS",DDERR_VERTICALBLANKINPROGRESS},
  127. {"DDERR_WASSTILLDRAWING",DDERR_WASSTILLDRAWING},
  128. {"DDERR_XALIGN",DDERR_XALIGN},
  129. {"DDERR_INVALIDDIRECTDRAWGUID",DDERR_INVALIDDIRECTDRAWGUID},
  130. {"DDERR_DIRECTDRAWALREADYCREATED",DDERR_DIRECTDRAWALREADYCREATED},
  131. {"DDERR_NODIRECTDRAWHW",DDERR_NODIRECTDRAWHW},
  132. {"DDERR_PRIMARYSURFACEALREADYEXISTS",DDERR_PRIMARYSURFACEALREADYEXISTS},
  133. {"DDERR_NOEMULATION",DDERR_NOEMULATION},
  134. {"DDERR_REGIONTOOSMALL",DDERR_REGIONTOOSMALL},
  135. {"DDERR_CLIPPERISUSINGHWND",DDERR_CLIPPERISUSINGHWND},
  136. {"DDERR_NOCLIPPERATTACHED",DDERR_NOCLIPPERATTACHED},
  137. {"DDERR_NOHWND",DDERR_NOHWND},
  138. {"DDERR_HWNDSUBCLASSED",DDERR_HWNDSUBCLASSED},
  139. {"DDERR_HWNDALREADYSET",DDERR_HWNDALREADYSET},
  140. {"DDERR_NOPALETTEATTACHED",DDERR_NOPALETTEATTACHED},
  141. {"DDERR_NOPALETTEHW",DDERR_NOPALETTEHW},
  142. {"DDERR_BLTFASTCANTCLIP",DDERR_BLTFASTCANTCLIP},
  143. {"DDERR_NOBLTHW",DDERR_NOBLTHW},
  144. {"DDERR_NODDROPSHW",DDERR_NODDROPSHW},
  145. {"DDERR_OVERLAYNOTVISIBLE",DDERR_OVERLAYNOTVISIBLE},
  146. {"DDERR_NOOVERLAYDEST",DDERR_NOOVERLAYDEST},
  147. {"DDERR_INVALIDPOSITION",DDERR_INVALIDPOSITION},
  148. {"DDERR_NOTAOVERLAYSURFACE",DDERR_NOTAOVERLAYSURFACE},
  149. {"DDERR_EXCLUSIVEMODEALREADYSET",DDERR_EXCLUSIVEMODEALREADYSET},
  150. {"DDERR_NOTFLIPPABLE",DDERR_NOTFLIPPABLE},
  151. {"DDERR_CANTDUPLICATE",DDERR_CANTDUPLICATE},
  152. {"DDERR_NOTLOCKED",DDERR_NOTLOCKED},
  153. {"DDERR_CANTCREATEDC",DDERR_CANTCREATEDC},
  154. {"DDERR_NODC",DDERR_NODC},
  155. {"DDERR_WRONGMODE",DDERR_WRONGMODE},
  156. {"DDERR_IMPLICITLYCREATED",DDERR_IMPLICITLYCREATED},
  157. {"DDERR_NOTPALETTIZED",DDERR_NOTPALETTIZED},
  158. {"DDERR_UNSUPPORTEDMODE",DDERR_UNSUPPORTEDMODE},
  159. {"END",0}
  160. };
  161. inline char * ErrorName(HRESULT err)
  162. {
  163. int e=0;
  164. while (strcmp(ErrorLookup[e].name,"END"))
  165. {
  166. if (err == ErrorLookup[e].errcode)
  167. return ErrorLookup[e].name;
  168. e++;
  169. };
  170. return "Unknown Error code";
  171. }
  172. class CLogfile
  173. {
  174. private:
  175. char smalltemp[10];
  176. HFILE fh;
  177. OFSTRUCT of;
  178. BOOL bHeaderWritten;
  179. char *cComment;
  180. char line[1000];
  181. LONG lStartPos;
  182. char Path[200];
  183. public:
  184. CLogfile(char * path, char * comment = 0,BOOL bAppend=FALSE)
  185. {
  186. if (path)
  187. strncpy(Path,path,199);
  188. fh = HFILE_ERROR;
  189. bHeaderWritten = FALSE;
  190. lStartPos = 0;
  191. //if the file does not exist, create it:
  192. if (GetFileAttributes(path) == 0xffffffff)
  193. fh = OpenFile(path,&of,OF_CREATE|OF_READWRITE|OF_SHARE_DENY_WRITE);
  194. else
  195. //first attempt to get a lock on the file...
  196. for (int i=0;i<20 && fh==HFILE_ERROR;i++)
  197. {
  198. if (bAppend)
  199. fh = OpenFile(path,&of, OF_READWRITE|OF_SHARE_DENY_WRITE);
  200. else
  201. fh = OpenFile(path,&of, OF_CREATE|OF_READWRITE|OF_SHARE_DENY_WRITE);
  202. if (fh==HFILE_ERROR)
  203. Sleep(1000);
  204. }
  205. if (fh==HFILE_ERROR)
  206. return;
  207. lStartPos = _llseek(fh,0,SEEK_END);
  208. cComment = comment;
  209. }
  210. void OutputHeader(void)
  211. {
  212. //now we have the file, write user/computer info:
  213. //write separator, comment if necessary and date and time:
  214. SYSTEMTIME st;
  215. GetLocalTime(&st);
  216. wsprintf(line,"----------------------------------------------------------\r\n");
  217. _lwrite(fh,line,strlen(line));
  218. if (cComment && strlen(cComment))
  219. {
  220. wsprintf(line,"%s\r\n",cComment);
  221. _lwrite(fh,line,strlen(line));
  222. }
  223. wsprintf(line,"Beginning test at %d:%02d on %d/%d/%d\r\n",st.wHour,st.wMinute,st.wYear,st.wMonth,st.wDay);
  224. _lwrite(fh,line,strlen(line));
  225. //write user's name:
  226. DWORD length = 100;
  227. wsprintf(line,"User Name:");
  228. WNetGetUser(NULL,line+strlen(line),&length);
  229. _lwrite(fh,line,strlen(line));
  230. //write computer's name:
  231. wsprintf(line,"\r\nComputer Name:");
  232. GetComputerName(line+strlen(line),&length);
  233. _lwrite(fh,line,strlen(line));
  234. //write display driver's name:
  235. wsprintf(line,"\r\nDisplay driver:");
  236. GetPrivateProfileString("boot.description","display.drv","(Unknown)",line+strlen(line),100,"system.ini");
  237. _lwrite(fh,line,strlen(line));
  238. _lwrite(fh,"\r\n",2);
  239. HDC hdc = GetDC(NULL);
  240. if (hdc)
  241. {
  242. wsprintf(line,"Starting resolution: %dx%dx%d\r\n",
  243. GetDeviceCaps(hdc,HORZRES)
  244. ,GetDeviceCaps(hdc,VERTRES)
  245. ,GetDeviceCaps(hdc,BITSPIXEL) );
  246. _lwrite(fh,line,strlen(line));
  247. ReleaseDC(NULL,hdc);
  248. }
  249. wsprintf(line,"- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \r\n");
  250. _lwrite(fh,line,strlen(line));
  251. bHeaderWritten = TRUE;
  252. }
  253. ~CLogfile()
  254. {
  255. SYSTEMTIME st;
  256. if(fh != HFILE_ERROR)
  257. {
  258. if (bHeaderWritten)
  259. {
  260. GetLocalTime(&st);
  261. wsprintf(line,"----------- Test ends at %d:%02d on %d/%d/%d -------------\r\n",st.wHour,st.wMinute,st.wYear,st.wMonth,st.wDay);
  262. _lwrite(fh,line,strlen(line));
  263. }
  264. _lclose(fh);
  265. }
  266. }
  267. CLogfile & operator << (DWORD dw)
  268. {
  269. if(fh == HFILE_ERROR)
  270. return *this;
  271. if(!bHeaderWritten)
  272. OutputHeader();
  273. wsprintf(smalltemp,"%08x",dw);
  274. _lwrite(fh,smalltemp,strlen(smalltemp));
  275. return *this;
  276. }
  277. CLogfile & operator << (LONG dw)
  278. {
  279. if(fh == HFILE_ERROR)
  280. return *this;
  281. if(!bHeaderWritten)
  282. OutputHeader();
  283. wsprintf(smalltemp,"%d",dw);
  284. _lwrite(fh,smalltemp,strlen(smalltemp));
  285. return *this;
  286. }
  287. CLogfile & operator << (void * p)
  288. {
  289. if(fh == HFILE_ERROR)
  290. return *this;
  291. if(!bHeaderWritten)
  292. OutputHeader();
  293. // 7/28/2000(a-JiTay): IA64: Use %p format specifier for 32/64-bit pointers and handles.
  294. wsprintf(smalltemp,"%p",p);
  295. _lwrite(fh,smalltemp,strlen(smalltemp));
  296. return *this;
  297. }
  298. CLogfile & operator << (char * cp)
  299. {
  300. if(fh == HFILE_ERROR)
  301. return *this;
  302. if(!bHeaderWritten)
  303. OutputHeader();
  304. while( *cp)
  305. *this << *cp++;
  306. return *this;
  307. }
  308. CLogfile & operator << (char c)
  309. {
  310. if(fh == HFILE_ERROR)
  311. return *this;
  312. if(!bHeaderWritten)
  313. OutputHeader();
  314. if (c=='\n')
  315. {
  316. wsprintf(smalltemp,"\r");
  317. _lwrite(fh,smalltemp,strlen(smalltemp));
  318. }
  319. wsprintf(smalltemp,"%c",c);
  320. _lwrite(fh,smalltemp,strlen(smalltemp));
  321. return *this;
  322. }
  323. CLogfile & operator << (CLogfile & log)
  324. {
  325. if(fh == HFILE_ERROR)
  326. return *this;
  327. if(!bHeaderWritten)
  328. OutputHeader();
  329. LONG pos = _llseek(log.fh,0,FILE_CURRENT);
  330. LONG from = _llseek(log.fh,log.lStartPos,FILE_BEGIN);
  331. char ch;
  332. *this << "= = = = = = = Snapshot of ";
  333. if (log.Path)
  334. *this << log.Path;
  335. else
  336. *this << "Unknown file";
  337. *this << " = = = = = = =\n";
  338. for (LONG j=0;j<pos-from;j++)
  339. {
  340. _lread(log.fh,&ch,1);
  341. *this << ch;
  342. }
  343. *this << "= = = = = = = = = Snapshot ends = = = = = = = = = = =\n";
  344. return *this;
  345. }
  346. };