Leaked source code of windows server 2003
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.

550 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. log.c
  5. Abstract:
  6. Implementation of the internal debug and support routines
  7. Author:
  8. Colin Brace April 5, 1999
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include <setpch.h>
  14. #include <dssetp.h>
  15. #include <loadfn.h>
  16. #include <samrpc.h>
  17. #include <samisrv.h>
  18. #include <nlrepl.h>
  19. #include <lmjoin.h>
  20. #include <netsetp.h>
  21. #include <lmaccess.h>
  22. #include <winsock2.h>
  23. #include <nspapi.h>
  24. #include <dsgetdcp.h>
  25. #include <lmremutl.h>
  26. #define UNICODE_BYTE_ORDER_MARK 0xFEFF
  27. //
  28. // Global handle to the log file
  29. //
  30. HANDLE DsRolepLogFile = NULL;
  31. CRITICAL_SECTION LogFileCriticalSection;
  32. #define LockLogFile() RtlEnterCriticalSection( &LogFileCriticalSection );
  33. #define UnlockLogFile() RtlLeaveCriticalSection( &LogFileCriticalSection );
  34. //
  35. // log file name
  36. //
  37. #define DSROLEP_LOGNAME L"\\debug\\DCPROMO.LOG"
  38. #define DSROLEP_BAKNAME L"\\debug\\DCPROMO.BAK"
  39. DWORD
  40. DsRolepInitializeLogHelper(
  41. IN DWORD TimesCalled
  42. )
  43. /*++
  44. Routine Description:
  45. Initializes the debugging log file used by DCPROMO and the dssetup apis
  46. N.B. This will not delete a previous log file; rather it will continue
  47. to use the same one.
  48. Arguments:
  49. None
  50. Returns:
  51. ERROR_SUCCESS - Success
  52. --*/
  53. {
  54. DWORD dwErr = ERROR_SUCCESS;
  55. WCHAR LogFileName[ MAX_PATH + 1 ];
  56. WCHAR bakLogFileName[ MAX_PATH + 1 ];
  57. WCHAR cBOM = UNICODE_BYTE_ORDER_MARK;
  58. BOOLEAN fSuccess;
  59. ASSERT(TimesCalled <= 2 && L"MoveFile failed to move file but reported success.");
  60. if (TimesCalled > 2) {
  61. DsRoleDebugOut(( DEB_ERROR,
  62. "MoveFile failed to move file but reported success.\n",
  63. dwErr ));
  64. return ERROR_GEN_FAILURE;
  65. }
  66. LockLogFile();
  67. //
  68. // Construct the log file name
  69. //
  70. if ( !GetWindowsDirectoryW( LogFileName,
  71. sizeof(LogFileName)/sizeof(*LogFileName) ) ) {
  72. dwErr = GetLastError();
  73. DsRoleDebugOut(( DEB_ERROR,
  74. "GetWindowsDirectory failed with %lu\n",
  75. dwErr ));
  76. goto Exit;
  77. }
  78. wcsncat( LogFileName, DSROLEP_LOGNAME, MAX_PATH-wcslen(LogFileName) );
  79. DsRoleDebugOut(( DEB_TRACE,
  80. "Logfile name: %ws\n",
  81. LogFileName ));
  82. //
  83. // Open the file
  84. //
  85. DsRolepLogFile = CreateFileW( LogFileName,
  86. GENERIC_WRITE | GENERIC_READ,
  87. FILE_SHARE_READ | FILE_SHARE_WRITE,
  88. NULL,
  89. OPEN_ALWAYS,
  90. FILE_ATTRIBUTE_NORMAL,
  91. NULL );
  92. if ( DsRolepLogFile == INVALID_HANDLE_VALUE ) {
  93. dwErr = GetLastError();
  94. DsRoleDebugOut(( DEB_ERROR,
  95. "CreateFile on %ws failed with %lu\n",
  96. LogFileName,
  97. dwErr ));
  98. DsRolepLogFile = NULL;
  99. goto Exit;
  100. }
  101. if ( ERROR_ALREADY_EXISTS != GetLastError() ) {
  102. //This is a unicode file so if it was just
  103. //created the Byte-order Mark needs to be
  104. //added to the beginning of the file.
  105. DWORD lpNumberOfBytesWritten = 0;
  106. if ( !WriteFile(DsRolepLogFile,
  107. (LPCVOID)&cBOM,
  108. sizeof(WCHAR),
  109. &lpNumberOfBytesWritten,
  110. NULL) )
  111. {
  112. dwErr = GetLastError();
  113. DsRoleDebugOut(( DEB_ERROR,
  114. "WriteFile on %ws failed with %lu\n",
  115. LogFileName,
  116. dwErr ));
  117. goto Exit;
  118. }
  119. ASSERT(lpNumberOfBytesWritten == sizeof(WCHAR));
  120. } else {
  121. //See if the opened file is UNICODE
  122. //if not move it and create a new file.
  123. WCHAR wcBuffer = 0;
  124. DWORD lpNumberOfBytesRead = 0;
  125. if ( !ReadFile(DsRolepLogFile,
  126. (LPVOID)&wcBuffer,
  127. sizeof(WCHAR),
  128. &lpNumberOfBytesRead,
  129. NULL) )
  130. {
  131. dwErr = GetLastError();
  132. DsRoleDebugOut(( DEB_ERROR,
  133. "ReadFile on %ws failed with %lu\n",
  134. LogFileName,
  135. dwErr ));
  136. goto Exit;
  137. }
  138. ASSERT(lpNumberOfBytesRead == sizeof(WCHAR));
  139. if (cBOM != wcBuffer) {
  140. //This is not a UNICODE FILE Move it.
  141. //Create a New Dcpromo Log
  142. //
  143. // Construct the bak log file name
  144. //
  145. if ( !GetWindowsDirectoryW( bakLogFileName,
  146. sizeof(bakLogFileName)/sizeof(*bakLogFileName) ) ) {
  147. dwErr = GetLastError();
  148. DsRoleDebugOut(( DEB_ERROR,
  149. "GetWindowsDirectory failed with %lu\n",
  150. dwErr ));
  151. goto Exit;
  152. }
  153. wcsncat( bakLogFileName, DSROLEP_BAKNAME, MAX_PATH-wcslen(bakLogFileName) );
  154. DsRoleDebugOut(( DEB_TRACE,
  155. "Logfile name: %ws\n",
  156. bakLogFileName ));
  157. if ( DsRolepLogFile ) {
  158. CloseHandle( DsRolepLogFile );
  159. DsRolepLogFile = NULL;
  160. }
  161. //move the file
  162. if ( !MoveFile(LogFileName,
  163. bakLogFileName) )
  164. {
  165. dwErr = GetLastError();
  166. DsRoleDebugOut(( DEB_ERROR,
  167. "MoveFile From %ws to %ws failed with %lu\n",
  168. LogFileName,
  169. bakLogFileName,
  170. dwErr ));
  171. goto Exit;
  172. }
  173. UnlockLogFile();
  174. return DsRolepInitializeLogHelper(TimesCalled+1);
  175. }
  176. }
  177. //No longer need read access so reopen the file
  178. //with just write access.
  179. if ( DsRolepLogFile ) {
  180. CloseHandle( DsRolepLogFile );
  181. DsRolepLogFile = NULL;
  182. }
  183. DsRolepLogFile = CreateFileW( LogFileName,
  184. GENERIC_WRITE,
  185. FILE_SHARE_READ | FILE_SHARE_WRITE,
  186. NULL,
  187. OPEN_ALWAYS,
  188. FILE_ATTRIBUTE_NORMAL,
  189. NULL );
  190. //
  191. // Goto to the end of the file
  192. //
  193. if( SetFilePointer( DsRolepLogFile,
  194. 0, 0,
  195. FILE_END ) == 0xFFFFFFFF ) {
  196. dwErr = GetLastError();
  197. DsRoleDebugOut(( DEB_ERROR,
  198. "SetFilePointer failed with %lu\n",
  199. dwErr ));
  200. goto Exit;
  201. }
  202. //
  203. // That's it
  204. //
  205. ASSERT( ERROR_SUCCESS == dwErr );
  206. Exit:
  207. if ( (ERROR_SUCCESS != dwErr)
  208. && (NULL != DsRolepLogFile) ) {
  209. CloseHandle( DsRolepLogFile );
  210. DsRolepLogFile = NULL;
  211. }
  212. UnlockLogFile();
  213. return( dwErr );
  214. }
  215. DWORD
  216. DsRolepInitializeLog(
  217. VOID
  218. )
  219. /*++
  220. Routine Description:
  221. Initializes the debugging log file used by DCPROMO and the dssetup apis
  222. N.B. This will not delete a previous log file; rather it will continue
  223. to use the same one.
  224. Arguments:
  225. None
  226. Returns:
  227. ERROR_SUCCESS - Success
  228. --*/
  229. {
  230. //caller the helper function for the first time.
  231. return DsRolepInitializeLogHelper(1);
  232. }
  233. DWORD
  234. DsRolepCloseLog(
  235. VOID
  236. )
  237. /*++
  238. Routine Description:
  239. Closes the debugging log file used by DCPROMO and the dssetup apis
  240. Arguments:
  241. None
  242. Returns:
  243. ERROR_SUCCESS - Success
  244. --*/
  245. {
  246. DWORD dwErr = ERROR_SUCCESS;
  247. LockLogFile();
  248. if ( DsRolepLogFile != NULL ) {
  249. CloseHandle( DsRolepLogFile );
  250. DsRolepLogFile = NULL;
  251. }
  252. UnlockLogFile();
  253. return( dwErr );
  254. }
  255. //
  256. // Stolen and hacked up from netlogon code
  257. //
  258. VOID
  259. DsRolepDebugDumpRoutine(
  260. IN DWORD DebugFlag,
  261. IN LPWSTR Format,
  262. va_list arglist
  263. )
  264. {
  265. #define DsRolepDebugDumpRoutine_BUFFERSIZE 1024
  266. WCHAR OutputBuffer[DsRolepDebugDumpRoutine_BUFFERSIZE];
  267. ULONG length;
  268. DWORD BytesWritten;
  269. SYSTEMTIME SystemTime;
  270. static BeginningOfLine = TRUE;
  271. //
  272. // If we don't have an open log file, just bail
  273. //
  274. if ( DsRolepLogFile == NULL ) {
  275. return;
  276. }
  277. length = 0;
  278. //
  279. // Handle the beginning of a new line.
  280. //
  281. //
  282. if ( BeginningOfLine ) {
  283. CHAR *Prolog;
  284. if ( FLAG_ON( DebugFlag, DEB_ERROR ) ) {
  285. Prolog = "[ERROR] ";
  286. } else if ( FLAG_ON( DebugFlag, DEB_WARN ) ) {
  287. Prolog = "[WARNING] ";
  288. } else if ( FLAG_ON( DebugFlag, DEB_TRACE )
  289. || FLAG_ON( DebugFlag, DEB_TRACE_DS ) ) {
  290. Prolog = "[INFO] ";
  291. } else {
  292. Prolog = "";
  293. }
  294. //
  295. // Put the timestamp at the begining of the line.
  296. //
  297. GetLocalTime( &SystemTime );
  298. length += (ULONG) wsprintfW( &OutputBuffer[length],
  299. L"%02u/%02u %02u:%02u:%02u %S",
  300. SystemTime.wMonth,
  301. SystemTime.wDay,
  302. SystemTime.wHour,
  303. SystemTime.wMinute,
  304. SystemTime.wSecond,
  305. Prolog );
  306. }
  307. //
  308. // Put a the information requested by the caller onto the line
  309. //
  310. length += (ULONG) wvsprintfW(&OutputBuffer[length],
  311. Format,
  312. arglist);
  313. BeginningOfLine = (length > 0 && OutputBuffer[length-1] == L'\n' );
  314. if ( BeginningOfLine ) {
  315. OutputBuffer[length-1] = L'\r';
  316. OutputBuffer[length] = L'\n';
  317. OutputBuffer[length+1] = L'\0';
  318. length++;
  319. }
  320. ASSERT( length <= sizeof( OutputBuffer ) / sizeof( WCHAR ) );
  321. //
  322. // Grab the lock
  323. //
  324. LockLogFile();
  325. //
  326. // Write the debug info to the log file.
  327. //
  328. if ( !WriteFile( DsRolepLogFile,
  329. OutputBuffer,
  330. length*sizeof(WCHAR),
  331. &BytesWritten,
  332. NULL ) ) {
  333. DsRoleDebugOut(( DEB_ERROR,
  334. "Log write of %ws failed with %lu\n",
  335. OutputBuffer,
  336. GetLastError() ));
  337. }
  338. DsRoleDebugOut(( DebugFlag,
  339. "%ws",
  340. OutputBuffer ));
  341. //
  342. // Release the lock
  343. //
  344. UnlockLogFile();
  345. return;
  346. }
  347. VOID
  348. DsRolepLogPrintRoutine(
  349. IN DWORD DebugFlag,
  350. IN LPSTR Format,
  351. ...
  352. )
  353. {
  354. PWCHAR WFormat = NULL;
  355. va_list arglist;
  356. DWORD WinErr = ERROR_SUCCESS;
  357. DWORD Bufsize = strlen(Format)+1;
  358. WFormat = (PWCHAR)malloc(Bufsize*sizeof(WCHAR));
  359. if ( WFormat ) {
  360. MultiByteToWideChar(CP_ACP,
  361. 0,
  362. Format,
  363. -1,
  364. WFormat,
  365. Bufsize
  366. );
  367. } else {
  368. DsRoleDebugOut(( DEB_ERROR,
  369. "Log write failed with %lu\n",
  370. ERROR_NOT_ENOUGH_MEMORY ));
  371. }
  372. va_start(arglist, Format);
  373. if ( WFormat ) {
  374. DsRolepDebugDumpRoutine( DebugFlag, WFormat, arglist );
  375. }
  376. va_end(arglist);
  377. if (WFormat) {
  378. free(WFormat);
  379. }
  380. }
  381. DWORD
  382. DsRolepSetAndClearLog(
  383. VOID
  384. )
  385. /*++
  386. Routine Description:
  387. Flushes the log and seeks to the end of the file
  388. Arguments:
  389. None
  390. Returns:
  391. ERROR_SUCCESS - Success
  392. --*/
  393. {
  394. DWORD dwErr = ERROR_SUCCESS;
  395. LockLogFile();
  396. if ( DsRolepLogFile != NULL ) {
  397. if( SetFilePointer( DsRolepLogFile,
  398. 0, 0,
  399. FILE_END ) == 0xFFFFFFFF ) {
  400. dwErr = GetLastError();
  401. }
  402. if( FlushFileBuffers( DsRolepLogFile ) == FALSE ) {
  403. dwErr = GetLastError();
  404. }
  405. }
  406. UnlockLogFile();
  407. return( dwErr );
  408. }