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.

839 lines
19 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <tchar.h>
  5. #include <stdarg.h>
  6. #include <time.h>
  7. #include "network.h"
  8. #include "idw_dbg.h"
  9. #include "server.h"
  10. /*++
  11. Filename : idw_dbg.cpp
  12. Description: Contains the idwlog1.dbg idwlog2.dbg error logging functions.
  13. Created by: Wally Ho
  14. History: Created on 31/01/2000.
  15. Modified to TCHAR from my implementation in the MPK test suite.
  16. 09.19.2001 Joe Holman fixes for idwlog bugs 409338, 399178, and 352810
  17. 10.03.2001 Joe Holman make the log file report a 'w' instead of a 'a' fopen call.
  18. 11.02.2001 Joe Holman Added code to make a connection to ntburnlab2 with particular user so we
  19. can authenticate when a machine is not in the same domain thus allowing
  20. the file copy of logs to succeed.
  21. 11.12.2001 Joe Holman Added language value to the output log.
  22. Contains these functions:
  23. 1. VOID OpenIdwlogDebugFile(DWORD dwPart);
  24. 2. VOID CloseIdwlogDebugFile(VOID);
  25. 3. VOID RemoveIdwlogDebugFile(DWORD dwPart);
  26. 4. VOID Idwlog (LPTSTR szMessage,...);
  27. --*/
  28. // Global
  29. FILE* fpIdwlogDebugFile;
  30. CONST DWORD MAX_SIZE_OF_DEBUG_FILE = 4000000;
  31. static CONST LPTSTR IDWLOG_LOG = TEXT("Idwlog.log");
  32. static CONST LPTSTR IDWLOGSERVICE_LOG = TEXT("IdwlogService.log");
  33. TCHAR szSuiteMask[MAX_PATH*2];
  34. TCHAR szProductType[MAX_PATH*2];
  35. #define CLEAR_LOG TRUE
  36. #define APPEND_LOG FALSE
  37. VOID
  38. MyLogger ( TCHAR * String, DWORD dwBuild, BOOL bClearLog, DWORD dwDelta )
  39. /*++
  40. Routine Description:
  41. This function does the following:
  42. - get's the computer name
  43. - tries to create the log directory for the build
  44. - opens the log file in append mode or overwrites
  45. - writes out the specified string
  46. - closes the log file
  47. Arguments:
  48. String - this is the text that we want to copy over to the server
  49. dwBuild - the build # for the machine
  50. bClearLog - if TRUE, we fopen with "w" (zero out), if FALSE, we fopen with "a" (append)
  51. Return Value:
  52. NONE
  53. Notes:
  54. NONE
  55. Author: Joe Holman (joehol) 09.20.2001
  56. --*/
  57. {
  58. FILE * stream;
  59. TCHAR szName[MAX_PATH];
  60. TCHAR szComputerName [ MAX_COMPUTERNAME_LENGTH + MAX_PATH] = "DefCompName";
  61. DWORD dwSize;
  62. dwSize = sizeof ( szComputerName );
  63. if ( GetComputerName ( szComputerName, &dwSize ) ) {
  64. // Try to make the directory name. This will only be succussful on the first instance for
  65. // for this build, but we need to do the operation always to make sure it gets created.
  66. //
  67. if ( dwBuild == 2600 ) { // For Service Pack builds we want to use minor and major build # also to differentiate.
  68. // We are going to use the format of:
  69. //
  70. // 2600.1001 (for internal use, we don't need to worry about having the major and minor data.
  71. //
  72. _stprintf ( szName, TEXT("\\\\ntburnlab2\\joehol\\logs\\%ld.%ld"), dwBuild, dwDelta );
  73. CreateDirectory ( szName, NULL );
  74. _stprintf ( szName, TEXT("\\\\ntburnlab2\\joehol\\logs\\%ld.%ld\\%s"), dwBuild, dwDelta, szComputerName );
  75. }
  76. else {
  77. _stprintf ( szName, TEXT("\\\\ntburnlab2\\joehol\\logs\\%ld"), dwBuild );
  78. CreateDirectory ( szName, NULL );
  79. _stprintf ( szName, TEXT("\\\\ntburnlab2\\joehol\\logs\\%ld\\%s"), dwBuild, szComputerName );
  80. }
  81. // Idwlog ( TEXT("MyLogger szName = %s.\n"), szName );
  82. if ( (stream = _tfopen ( szName, (bClearLog?TEXT("w"):TEXT("a")) )) != NULL ) {
  83. TCHAR szBuf[2*MAX_PATH];
  84. _stprintf ( szBuf, TEXT("%s"), String );
  85. if ( fwrite ( szBuf, 1, _tcsclen(szBuf), stream ) < 1 ) {
  86. Idwlog ( TEXT("MyLogger ERROR fwrite had an error writing.\n") );
  87. }
  88. fclose ( stream );
  89. }
  90. else {
  91. Idwlog ( TEXT("MyLogger ERROR fopen had a problem on (%s).\n"), szName );
  92. }
  93. }
  94. else {
  95. Idwlog ( TEXT("MyLogger ERROR GetComputerName gle = %ld\n"), GetLastError() );
  96. }
  97. }
  98. TCHAR * ShowProductType ( DWORD dwProductType )
  99. /*++
  100. Routine Description:
  101. This function does the following:
  102. - determines what the product type is and returns it in string format
  103. Arguments:
  104. dwProductType - the bit mask to examine
  105. Return Value:
  106. Pointer to global string to display.
  107. Notes:
  108. NONE
  109. Author: Joe Holman (joehol) 09.20.2001
  110. --*/
  111. {
  112. switch ( dwProductType ) {
  113. case VER_NT_WORKSTATION :
  114. _tcscpy ( szProductType, TEXT("VER_NT_WORKSTATION") );
  115. break;
  116. case VER_NT_DOMAIN_CONTROLLER :
  117. _tcscpy ( szProductType, TEXT("VER_NT_DOMAIN_CONTROLLER") );
  118. break;
  119. case VER_NT_SERVER :
  120. _tcscpy ( szProductType, TEXT("VER_NT_SERVER") );
  121. break;
  122. default :
  123. strcpy ( szProductType, "ERRORUNKNOWNPRODUCTTYPE" );
  124. }
  125. return ( szProductType );
  126. }
  127. TCHAR * ShowSuiteMask ( DWORD dwSuiteMask )
  128. /*++
  129. Routine Description:
  130. This function does the following:
  131. - examines the suite mask provided and appends each suite characteristic to the global string.
  132. Arguments:
  133. dwSuiteMask - suite mask to do bit compares against.
  134. Return Value:
  135. Pointer to global string to display.
  136. Notes:
  137. NONE
  138. Author: Joe Holman (joehol) 09.20.2001
  139. --*/
  140. {
  141. _tcscpy ( szSuiteMask, " " );
  142. if ( dwSuiteMask & VER_SUITE_SMALLBUSINESS ) {
  143. _tcscat( szSuiteMask, TEXT("Small Business, ") );
  144. }
  145. if ( dwSuiteMask & VER_SUITE_BACKOFFICE ) {
  146. _tcscat( szSuiteMask, TEXT("BackOffice, ") );
  147. }
  148. if ( dwSuiteMask & VER_SUITE_COMMUNICATIONS ) {
  149. _tcscat( szSuiteMask, TEXT("Communications, ") );
  150. }
  151. if ( dwSuiteMask & VER_SUITE_TERMINAL ) {
  152. _tcscat( szSuiteMask, TEXT("Terminal, ") );
  153. }
  154. if ( dwSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED ) {
  155. _tcscat( szSuiteMask, TEXT("Small Business Restricted, ") );
  156. }
  157. if ( dwSuiteMask & VER_SUITE_EMBEDDEDNT ) {
  158. _tcscat( szSuiteMask, TEXT("Embedded NT, ") );
  159. }
  160. if ( dwSuiteMask & VER_SUITE_SINGLEUSERTS ) {
  161. _tcscat( szSuiteMask, TEXT("Supports Single User Terminal Service, ") );
  162. }
  163. if ( dwSuiteMask & VER_SUITE_PERSONAL ) {
  164. _tcscat( szSuiteMask, TEXT("Home Edition, ") );
  165. }
  166. if ( dwSuiteMask & VER_SUITE_DATACENTER ) {
  167. _tcscat( szSuiteMask, TEXT("Data Center, ") );
  168. }
  169. if ( dwSuiteMask & VER_SUITE_ENTERPRISE ) {
  170. _tcscat( szSuiteMask, TEXT("Enterprise(old Advanced Server), ") );
  171. }
  172. if ( dwSuiteMask & VER_SUITE_BLADE ) {
  173. _tcscat( szSuiteMask, TEXT("Blade, ") );
  174. }
  175. return ( szSuiteMask );
  176. }
  177. typedef struct _tagLANGINFO {
  178. LANGID LangID;
  179. INT Count;
  180. } LANGINFO,*PLANGINFO;
  181. BOOL
  182. CALLBACK
  183. EnumLangProc(
  184. HANDLE hModule, // resource-module handle
  185. LPCTSTR lpszType, // pointer to resource type
  186. LPCTSTR lpszName, // pointer to resource name
  187. WORD wIDLanguage, // resource language identifier
  188. LONG_PTR lParam // application-defined parameter
  189. )
  190. /*++
  191. Routine Description:
  192. Callback that counts versions stamps.
  193. Arguments:
  194. Details of version enumerated version stamp. (Ignore.)
  195. Return Value:
  196. Indirectly thru lParam: count, langID
  197. --*/
  198. {
  199. PLANGINFO LangInfo;
  200. LangInfo = (PLANGINFO) lParam;
  201. LangInfo->Count++;
  202. //
  203. // for localized build contains multiple resource,
  204. // it usually contains 0409 as backup lang.
  205. //
  206. // if LangInfo->LangID != 0 means we already assigned an ID to it
  207. //
  208. // so when wIDLanguage == 0x409, we keep the one we got from last time
  209. //
  210. if ((wIDLanguage == 0x409) && (LangInfo->LangID != 0)) {
  211. return TRUE;
  212. }
  213. LangInfo->LangID = wIDLanguage;
  214. return TRUE; // continue enumeration
  215. }
  216. VOID
  217. CopySetupErrorLog ( LPINSTALL_DATA pID )
  218. /*++
  219. Routine Description:
  220. This function copies the machines SetupError.log file
  221. to one of our specified servers for later analysis.
  222. It will copy it to the following directory:
  223. \\ntburnlab2\joehol\logs\<build#>\<machinename>
  224. Arguments:
  225. NONE
  226. Return Value:
  227. NONE
  228. Notes:
  229. This function should silently fail gracefully if any error
  230. is encountered.
  231. Author: Joe Holman (joehol) 09.20.2001
  232. --*/
  233. {
  234. TCHAR szLog[2*MAX_PATH];
  235. TCHAR szWindowsDirectory[MAX_PATH];
  236. TCHAR Line[2*MAX_PATH];
  237. UINT ui;
  238. FILE* fp;
  239. OSVERSIONINFOEX osv;
  240. BOOL b;
  241. DWORD dwBuild = 0;
  242. NETRESOURCE NetResource;
  243. TCHAR szRemoteName [MAX_PATH];
  244. TCHAR szPassWord [ MAX_PATH ];
  245. TCHAR szUserId [ MAX_PATH ];
  246. DWORD dwError=0;
  247. LPCTSTR Type = (LPCTSTR) RT_VERSION;
  248. LPCTSTR Name = (LPCTSTR) 1;
  249. LANGINFO LangInfo;
  250. Idwlog ( TEXT("Entering CopySetupErrorLog.\n") );
  251. Idwlog ( TEXT("CopySetupErrorLog pID.szSystemBuildSourceLocation = %s\n"), pID->szSystemBuildSourceLocation );
  252. Idwlog ( TEXT("CopySetupErrorLog pID.szInstallingBuildSourceLocation = %s\n"), pID->szInstallingBuildSourceLocation );
  253. Idwlog ( TEXT("CopySetupErrorLog g_InstallData.dwInstallingBuildDelta = %ld\n"), g_InstallData.dwInstallingBuildDelta );
  254. // Get the windows directory for the machine.
  255. //
  256. ui = GetWindowsDirectory ( szWindowsDirectory, MAX_PATH );
  257. if ( ui == 0 ) {
  258. Idwlog ( TEXT("CopySetupErrorLog ERROR - GetWindowsDirectory gle = %ld\n"), GetLastError());
  259. return;
  260. }
  261. // Gain access to the machine via a user and password since a lot of machines are NOT
  262. // setup on the same domain and thus cannot authenticate unless we specify this.
  263. // We will log an error if this doesn't work, but we won't stop.
  264. //
  265. _stprintf(szRemoteName, TEXT("%s"), SETUPLOGS_MACH);
  266. _stprintf(szPassWord, TEXT("%s"), SETUPLOGS_PW);
  267. _stprintf(szUserId, TEXT("%s"), SETUPLOGS_USER);
  268. // Setup the memory for the connection.
  269. ZeroMemory( &NetResource, sizeof( NetResource ) );
  270. NetResource.dwType = RESOURCETYPE_DISK ;
  271. NetResource.lpLocalName = NULL;
  272. NetResource.lpRemoteName = szRemoteName;
  273. NetResource.lpProvider = NULL;
  274. _stprintf(szUserId, TEXT("%s"), SETUPLOGS_USER );
  275. dwError = WNetAddConnection2( &NetResource, szPassWord, szUserId, 0 );
  276. //Idwlog(TEXT("WNetAddConnection2 %s [dwError=%ld] using: %s, %s, %s\n"), (dwError==NO_ERROR)?TEXT("OK"):TEXT("ERROR"), dwError, szRemoteName, szUserId, szPassWord );
  277. Idwlog(TEXT("WNetAddConnection2 %s [dwError=%ld] using: %s\n"), (dwError==NO_ERROR)?TEXT("OK"):TEXT("ERROR"), dwError, szRemoteName );
  278. // Write the header out to the log file.
  279. //
  280. // Note: the first writes clear the log file.
  281. //
  282. ZeroMemory (&osv, sizeof(osv) );
  283. osv.dwOSVersionInfoSize = sizeof ( OSVERSIONINFOEX );
  284. b = GetVersionEx ( (OSVERSIONINFO * ) &osv );
  285. if ( !b ) {
  286. Idwlog ( TEXT("CopySetupErrorLog ERROR GetVersionEx FAILed, gle = %ld\n"), GetLastError());
  287. dwBuild = 0;
  288. MyLogger ( TEXT("IdwLog Header (GetVersionEx ERROR.)\n"), dwBuild, CLEAR_LOG, g_InstallData.dwInstallingBuildDelta );
  289. }
  290. else {
  291. dwBuild = osv.dwBuildNumber;
  292. Idwlog ( TEXT("CopySetupErrorLog retreived os version info. dwBuild = %ld\n"), dwBuild );
  293. _stprintf ( szLog, TEXT ("IdwLog\nosv.dwOSVersionInfoSize = %x\nosv.dwMajorVersion = %d\nosv.dwMinorVersion = %d\nosv.dwBuildNumber = %d\nosv.dwPlatformId = %x\nosv.szCSDVersion = %s\nosv.wServicePackMajor = %x\nosv.wServicePackMinor = %x\nosv.wSuiteMask = %x (%s)\nosv.wProductType = %x (%s)\nszSystemBuildSource = %s\nszInstallingBuildSource = %s\n"),
  294. osv.dwOSVersionInfoSize,
  295. osv.dwMajorVersion,
  296. osv.dwMinorVersion,
  297. osv.dwBuildNumber,
  298. osv.dwPlatformId,
  299. osv.szCSDVersion,
  300. osv.wServicePackMajor,
  301. osv.wServicePackMinor,
  302. osv.wSuiteMask,
  303. ShowSuiteMask (osv.wSuiteMask),
  304. osv.wProductType,
  305. ShowProductType (osv.wProductType),
  306. pID->szSystemBuildSourceLocation,
  307. pID->szInstallingBuildSourceLocation
  308. );
  309. MyLogger ( szLog, dwBuild, CLEAR_LOG, g_InstallData.dwInstallingBuildDelta) ;
  310. }
  311. // Write out the language information.
  312. //
  313. //
  314. ZeroMemory(&LangInfo,sizeof(LangInfo));
  315. EnumResourceLanguages(
  316. GetModuleHandle(TEXT("ntdll.dll")),
  317. Type,
  318. Name,
  319. (ENUMRESLANGPROC) EnumLangProc,
  320. (LONG_PTR) &LangInfo );
  321. _stprintf ( szLog, "LangInfo.LangID = %X\n\n", LangInfo.LangID );
  322. MyLogger ( szLog, dwBuild, APPEND_LOG, g_InstallData.dwInstallingBuildDelta );
  323. // Open the setup error log.
  324. //
  325. _stprintf ( szLog, TEXT("%s\\setuperr.log"), szWindowsDirectory );
  326. fp = _tfopen ( szLog, TEXT("r") );
  327. if ( fp == NULL ) {
  328. Idwlog ( TEXT("CopySetupErrorLog ERROR Couldn't open log file: %s\n"), szLog );
  329. return;
  330. }
  331. Idwlog ( TEXT("CopySetupErrorLog opened local setuperr.log file.\n") );
  332. while ( _fgetts ( Line, MAX_PATH, fp ) ) {
  333. // Prepend our tag text and write to the Server.
  334. //
  335. _stprintf ( szLog, TEXT("SetupErr.Log ERROR: %s"), Line );
  336. MyLogger ( szLog, dwBuild, APPEND_LOG, g_InstallData.dwInstallingBuildDelta );
  337. }
  338. fclose ( fp );
  339. Idwlog ( TEXT("CopySetupErrorLog finished.\n") );
  340. }
  341. VOID
  342. OpenIdwlogDebugFile(DWORD dwPart)
  343. /*++
  344. Routine Description:
  345. This will open a logfile for the dbg output for the idwlog
  346. The parameter it takes will let it write a *.log file for either
  347. Part1 or Part two of the tools execution.
  348. Arguments:
  349. 1 for service otherwise its idwlog.log.
  350. Return Value:
  351. NONE
  352. Author: Wally Ho (wallyho) Jan 31st, 2000
  353. --*/
  354. {
  355. TCHAR sztimeClock[128];
  356. TCHAR sztimeDate[128];
  357. TCHAR szmsg[MAX_PATH];
  358. TCHAR szIdwlogFile[30];
  359. TCHAR szIdwlogFileAndPath[100];
  360. TCHAR szSystemDrive[4];
  361. BOOL bUseSysDrive;
  362. HANDLE hTestExistence;
  363. WIN32_FIND_DATA ffd;
  364. UINT i;
  365. TCHAR szLogDirectoryToCreate[100] = TEXT("c:\\idwlog");
  366. fpIdwlogDebugFile = NULL;
  367. // Determine which part is the one we want.
  368. if (1 == dwPart){
  369. _tcscpy(szIdwlogFile,IDWLOGSERVICE_LOG );
  370. }
  371. else {
  372. _tcscpy(szIdwlogFile, IDWLOG_LOG );
  373. }
  374. // Do a look for where we wrote the file first.
  375. // The case is this: we install with a system on C drive.
  376. // We install to d: drive. D drive boots up; we write the dbg
  377. // on system root d:. This splits it from the initial write.
  378. // This will find it if its on C.
  379. // if it doesn't find it then we default to system drive.
  380. bUseSysDrive = TRUE;
  381. for (i= TEXT('c'); i <= TEXT('z'); i++){
  382. _stprintf ( szIdwlogFileAndPath,
  383. TEXT("%c:\\idwlog\\Idwlo*.dbg"), i);
  384. hTestExistence = FindFirstFile(szIdwlogFileAndPath, &ffd);
  385. if (INVALID_HANDLE_VALUE != hTestExistence){
  386. FindClose(hTestExistence);
  387. // Delete Old DBG files.
  388. //
  389. _stprintf ( szIdwlogFileAndPath, TEXT("%c:\\idwlog\\%s"), i, IDWLOGSERVICE_LOG );
  390. SetFileAttributes(szIdwlogFileAndPath,FILE_ATTRIBUTE_NORMAL);
  391. DeleteFile( szIdwlogFileAndPath);
  392. _stprintf ( szIdwlogFileAndPath, TEXT("%c:\\idwlog\\%s"), i, IDWLOG_LOG );
  393. SetFileAttributes(szIdwlogFileAndPath,FILE_ATTRIBUTE_NORMAL);
  394. DeleteFile( szIdwlogFileAndPath);
  395. }
  396. }
  397. for (i= TEXT('c'); i <= TEXT('z'); i++){
  398. _stprintf ( szIdwlogFileAndPath,
  399. TEXT("%c:\\idwlog\\%s"), i,szIdwlogFile);
  400. hTestExistence = FindFirstFile(szIdwlogFileAndPath, &ffd);
  401. if (INVALID_HANDLE_VALUE != hTestExistence){
  402. // We found a log file in this case here.
  403. //
  404. bUseSysDrive = FALSE;
  405. FindClose(hTestExistence);
  406. _stprintf ( szIdwlogFileAndPath,
  407. TEXT("%c:\\idwlog\\%s"), i, szIdwlogFile);
  408. // Check for FileSize if Greater that 500,000 bytes then delete it.
  409. if (ffd.nFileSizeLow >= MAX_SIZE_OF_DEBUG_FILE ) {
  410. SetFileAttributes(szIdwlogFileAndPath,FILE_ATTRIBUTE_NORMAL);
  411. DeleteFile( szIdwlogFileAndPath);
  412. }
  413. break;
  414. }
  415. }
  416. if (TRUE == bUseSysDrive){
  417. // Get the system Drive
  418. //
  419. if ( 0 == GetEnvironmentVariable(TEXT("SystemDrive"),szSystemDrive, 4)) {
  420. //
  421. // Default to C: (we're probably running on Win9x where there is
  422. // no SystemDrive envinronment variable)
  423. //
  424. _tcscpy(szSystemDrive, TEXT("C:"));
  425. }
  426. _stprintf(szIdwlogFileAndPath,TEXT("%s\\idwlog\\%s"),
  427. szSystemDrive,szIdwlogFile);
  428. _stprintf( szLogDirectoryToCreate, TEXT("%s\\idwlog"), szSystemDrive ); // new
  429. }
  430. else {
  431. _stprintf( szLogDirectoryToCreate, TEXT("%c\\idwlog"), szIdwlogFileAndPath[0] ); // new, szIdwlogFileAndPath filled out above.
  432. }
  433. // We want to store the logs in the our idwlog directory from the root, in order to fix bug #352810 - on logon, non-admin can't write log.
  434. CreateDirectory ( szLogDirectoryToCreate, NULL ); // don't check return code since it will fail in some cases if exist.
  435. fpIdwlogDebugFile = _tfopen(szIdwlogFileAndPath,TEXT("a"));
  436. if(NULL == fpIdwlogDebugFile) {
  437. // nothing we can do if the logfile is not formed?
  438. //_tprintf ( TEXT("ERROR - Could not open log file: %s\n"), szIdwlogFileAndPath );
  439. ExitProcess(GetLastError());
  440. }
  441. _tstrtime(sztimeClock);
  442. _tstrdate(sztimeDate);
  443. _stprintf(szmsg,TEXT("[Started on %s %s]\n"), sztimeDate, sztimeClock);
  444. _ftprintf( fpIdwlogDebugFile,TEXT("%s"), szmsg);
  445. /*** This is too annoying to have it hidden, so I'm removing it. JoeHol 09.17.2001
  446. if(FALSE == SetFileAttributes(szIdwlogFileAndPath, FILE_ATTRIBUTE_HIDDEN)) {
  447. Idwlog(TEXT("OpenIdwlogDebugFile ERROR - Could not set the debug file to Hidden.\n"));
  448. }
  449. ***/
  450. return;
  451. }
  452. VOID
  453. CloseIdwlogDebugFile(VOID)
  454. /*++
  455. Routine Description:
  456. This will close the logfile for the dbg output for the idwlog
  457. Arguments:
  458. NONE
  459. Return Value:
  460. NONE
  461. Author: Wally Ho (wallyho) Jan 31st, 2000
  462. --*/
  463. {
  464. if ( NULL != fpIdwlogDebugFile){
  465. fclose(fpIdwlogDebugFile);
  466. fpIdwlogDebugFile = NULL;
  467. }
  468. }
  469. VOID
  470. RemoveIdwlogDebugFile(DWORD dwPart)
  471. /*++
  472. Routine Description:
  473. This will remove the logfile for the dbg output for the idwlog
  474. Arguments:
  475. NONE
  476. Return Value:
  477. NONE
  478. Author: Wally Ho (wallyho) Jan 31st, 2000
  479. --*/
  480. {
  481. TCHAR szIdwlogFile[50];
  482. TCHAR szIdwlogFileAndPath[100];
  483. HANDLE hTestExistence;
  484. WIN32_FIND_DATA ffd;
  485. UINT i;
  486. // Determine which part is the one we want.
  487. if (1 == dwPart){
  488. _tcscpy(szIdwlogFile, IDWLOGSERVICE_LOG );
  489. }
  490. else
  491. _tcscpy(szIdwlogFile, IDWLOG_LOG );
  492. // Search all drives and kill the idwlog.dbg file
  493. for (i= TEXT('c'); i <= TEXT('z'); i++){
  494. _stprintf ( szIdwlogFileAndPath,
  495. TEXT("%c:\\idwlog\\%s"), i,szIdwlogFile);
  496. hTestExistence = FindFirstFile(szIdwlogFileAndPath, &ffd);
  497. if (INVALID_HANDLE_VALUE != hTestExistence){
  498. FindClose(hTestExistence);
  499. _stprintf ( szIdwlogFileAndPath,
  500. TEXT("%c:\\idwlog\\%s"), i,szIdwlogFile);
  501. // Make sure the file is removed so we have a fresh file everytime.
  502. _tremove(szIdwlogFile);
  503. break;
  504. }
  505. }
  506. }
  507. VOID
  508. Idwlog (LPTSTR szMessage,...)
  509. /*++
  510. Routine Description:
  511. This is the logging function for the idwlog.
  512. It behaves much like printf.
  513. Arguments:
  514. same as printf.
  515. Return Value:
  516. NONE
  517. Author: Wally Ho (wallyho) Jan 31st, 2000
  518. --*/
  519. {
  520. va_list vaArgs;
  521. time_t t;
  522. TCHAR szTimeBuffer[30];
  523. if ( NULL != fpIdwlogDebugFile) {
  524. // Write the time to the log.
  525. time(&t);
  526. _stprintf ( szTimeBuffer, TEXT("%s"), ctime(&t) );
  527. // ctime addes a new line to the buffer. Erase it here.
  528. szTimeBuffer[_tcslen(szTimeBuffer) - 1] = TEXT('\0');
  529. _ftprintf( fpIdwlogDebugFile, TEXT("[%s] "),szTimeBuffer);
  530. // Write the formatted string to the log.
  531. va_start( vaArgs, szMessage );
  532. _vftprintf( fpIdwlogDebugFile, szMessage, vaArgs );
  533. va_end ( vaArgs );
  534. // Flush the stream
  535. fflush(fpIdwlogDebugFile);
  536. }
  537. }