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.

1112 lines
27 KiB

  1. /* dbg.cpp */
  2. #include "precomp.h"
  3. #include <oprahcom.h>
  4. #include <cstring.hpp>
  5. #include <regentry.h>
  6. #include <confreg.h>
  7. #include <confdbg.h>
  8. #include <avUtil.h>
  9. PSECURITY_DESCRIPTOR CreateSd( VOID);
  10. BOOL CreateSids( PSID *BuiltInAdministrators, PSID *PowerUsers, PSID *AuthenticatedUsers);
  11. #ifdef NM_DEBUG /* Almost the whole file */
  12. // Special Debugbreak macro
  13. #if defined (_M_IX86)
  14. #define _DbgBreak() __asm { int 3 }
  15. #else
  16. #define _DbgBreak() DebugBreak()
  17. #endif
  18. // Special Mutex Macros
  19. #define ACQMUTEX(hMutex) WaitForSingleObject(hMutex, INFINITE)
  20. #define RELMUTEX(hMutex) ReleaseMutex(hMutex)
  21. // Constant for GlobalAddAtom
  22. const int CCHMAX_ATOM = 255;
  23. // Local Variables
  24. static PNMDBG _gpDbg = NULL; // Shared data in mmf after zone info
  25. static HANDLE _ghMutexFile = NULL; // Mutex for writing to file
  26. static PZONEINFO _gprgZoneInfo = NULL; // the address in which the zone is mapped,points to an array of zones
  27. static HANDLE _ghDbgZoneMap = NULL; // the handle of the memory mapped file for zones
  28. static HANDLE _ghDbgZoneMutex = NULL; // Mutex for accessing Zone information
  29. static long _gLockCount = 0;
  30. VOID DbgCurrentTime(PCHAR psz);
  31. /* _ D B G P R I N T F */
  32. /*-------------------------------------------------------------------------
  33. %%Function: _DbgPrintf
  34. The main, low level, debug output routine.
  35. -------------------------------------------------------------------------*/
  36. static VOID WINAPI _DbgPrintf(LPCSTR pszFile, PCSTR pszPrefix, PCSTR pszFormat, va_list ap)
  37. {
  38. CHAR szOutput[1024];
  39. PCHAR pszOutput = szOutput;
  40. UINT cch;
  41. if (NULL == _gprgZoneInfo)
  42. return;
  43. if (DBG_FMTTIME_NONE != _gpDbg->uShowTime)
  44. {
  45. DbgCurrentTime(pszOutput);
  46. pszOutput += lstrlenA(pszOutput);
  47. }
  48. if (_gpDbg->fShowThreadId)
  49. {
  50. wsprintfA(pszOutput, "[%04X] ", GetCurrentThreadId());
  51. pszOutput += lstrlenA(pszOutput);
  52. }
  53. if (_gpDbg->fShowModule)
  54. {
  55. CHAR szFile[MAX_PATH];
  56. if ((NULL == pszPrefix) || ('\0' == *pszPrefix))
  57. {
  58. GetModuleFileNameA(NULL, szFile, sizeof(szFile));
  59. pszPrefix = ExtractFileNameA(szFile);
  60. }
  61. lstrcpyA(pszOutput, pszPrefix);
  62. pszOutput += lstrlenA(pszOutput);
  63. lstrcpyA(pszOutput, " ");
  64. pszOutput += 1;
  65. }
  66. wvsprintfA(pszOutput, pszFormat, ap);
  67. // Append carriage return, if necessary
  68. // WARNING: This code is not DBCS-safe.
  69. cch = lstrlenA(szOutput);
  70. if (szOutput[cch-1] == '\n')
  71. {
  72. if (szOutput[cch-2] != '\r')
  73. {
  74. lstrcpyA(&szOutput[cch-1], "\r\n");
  75. cch++;
  76. }
  77. }
  78. else
  79. {
  80. lstrcpyA(&szOutput[cch], "\r\n");
  81. cch += 2;
  82. }
  83. // Output to debug handler
  84. if (_gpDbg->fOutputDebugString)
  85. {
  86. OutputDebugStringA(szOutput);
  87. }
  88. // Output to File
  89. if (_gpDbg->fFileOutput || (NULL != pszFile))
  90. {
  91. HANDLE hFile;
  92. DWORD dw;
  93. // Lock access to file
  94. ACQMUTEX(_ghMutexFile);
  95. if (NULL == pszFile)
  96. pszFile = _gpDbg->szFile;
  97. // open a log file for appending. create if does not exist
  98. hFile = CreateFileA(pszFile, GENERIC_WRITE, 0, NULL,
  99. OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  100. if (hFile != INVALID_HANDLE_VALUE)
  101. {
  102. // seek to end of file
  103. dw = SetFilePointer(hFile, 0, NULL, FILE_END);
  104. #ifdef TEST /* Test/Retail version truncates at 40K */
  105. if (dw > 0x040000)
  106. {
  107. CloseHandle(hFile);
  108. hFile = CreateFileA(pszFile, GENERIC_WRITE, 0, NULL,
  109. TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  110. }
  111. if (INVALID_HANDLE_VALUE != hFile)
  112. #endif
  113. {
  114. WriteFile(hFile, szOutput, lstrlenA(szOutput), &dw, NULL);
  115. CloseHandle(hFile);
  116. }
  117. }
  118. // Unlock access to file
  119. RELMUTEX(_ghMutexFile);
  120. }
  121. // Output to viewer. This is at the end of the function because
  122. // we potentially truncate szOutput.
  123. if ((_gpDbg->fWinOutput) && (NULL != _gpDbg->hwndCtrl))
  124. {
  125. // Make sure that the string doesn't exceed the maximum atom size.
  126. // WARNING: This code is not DBCS-safe.
  127. static const CHAR szTruncatedSuffix[] = "...\r\n";
  128. static const int cchTruncatedSuffix = ARRAY_ELEMENTS(szTruncatedSuffix) - 1;
  129. if (CCHMAX_ATOM < cch)
  130. {
  131. lstrcpyA(&szOutput[CCHMAX_ATOM - cchTruncatedSuffix], szTruncatedSuffix);
  132. }
  133. ATOM aDbgAtom = GlobalAddAtomA(szOutput);
  134. if (aDbgAtom)
  135. {
  136. if (!PostMessage(_gpDbg->hwndCtrl, _gpDbg->msgDisplay, (WPARAM)aDbgAtom, 0L))
  137. {
  138. // Unable to post Message, so free the atom
  139. GlobalDeleteAtom(aDbgAtom);
  140. }
  141. }
  142. }
  143. }
  144. PSTR WINAPI DbgZPrintf(HDBGZONE hZone, UINT iZone, PSTR pszFormat,...)
  145. {
  146. CHAR sz[MAXSIZE_OF_MODULENAME+MAXSIZE_OF_ZONENAME+1];
  147. PCHAR psz;
  148. va_list v1;
  149. va_start(v1, pszFormat);
  150. if ((NULL != hZone) && (iZone < MAXNUM_OF_ZONES))
  151. {
  152. wsprintfA(sz, "%hs:%hs", ((PZONEINFO) hZone)->pszModule, ((PZONEINFO) hZone)->szZoneNames[iZone]);
  153. psz = sz;
  154. }
  155. else
  156. {
  157. psz = NULL;
  158. }
  159. if ((NULL != hZone) && ('\0' != ((PZONEINFO) hZone)->szFile[0]))
  160. {
  161. // Use the private module output filename, if specified
  162. _DbgPrintf(((PZONEINFO) hZone)->szFile, psz, pszFormat, v1);
  163. }
  164. else
  165. {
  166. _DbgPrintf(NULL, psz, pszFormat, v1);
  167. }
  168. va_end(v1);
  169. return pszFormat;
  170. }
  171. PSTR WINAPI DbgZVPrintf(HDBGZONE hZone, UINT iZone, PSTR pszFormat, va_list ap)
  172. {
  173. CHAR sz[MAXSIZE_OF_MODULENAME+MAXSIZE_OF_ZONENAME+1];
  174. PCHAR psz;
  175. if ((NULL != hZone) && (iZone < MAXNUM_OF_ZONES))
  176. {
  177. wsprintfA(sz, "%hs:%hs", ((PZONEINFO) hZone)->pszModule, ((PZONEINFO) hZone)->szZoneNames[iZone]);
  178. psz = sz;
  179. }
  180. else
  181. {
  182. psz = NULL;
  183. }
  184. if ((NULL != hZone) && ('\0' != ((PZONEINFO) hZone)->szFile[0]))
  185. {
  186. // Use the private module output filename, if specified
  187. _DbgPrintf(((PZONEINFO) hZone)->szFile, psz, pszFormat, ap);
  188. }
  189. else
  190. {
  191. _DbgPrintf(NULL, psz, pszFormat, ap);
  192. }
  193. return pszFormat;
  194. }
  195. VOID WINAPI DbgPrintf(PCSTR pszPrefix, PCSTR pszFormat, va_list ap)
  196. {
  197. _DbgPrintf(NULL, pszPrefix, pszFormat, ap);
  198. }
  199. VOID NMINTERNAL DbgInitEx(HDBGZONE * phDbgZone, PCHAR * psz, UINT cZones, long ulZoneDefault)
  200. {
  201. UINT i;
  202. HDBGZONE hDbgZone;
  203. DBGZONEINFO dbgZoneParm;
  204. //DbgMsg("Module %s (%d zones)", *psz, cZones);
  205. InterlockedIncrement( &_gLockCount );
  206. InitDbgZone();
  207. if (cZones > MAXNUM_OF_ZONES)
  208. cZones = MAXNUM_OF_ZONES;
  209. ZeroMemory(&dbgZoneParm, sizeof(dbgZoneParm));
  210. // First string is the module name
  211. lstrcpynA(dbgZoneParm.pszModule, *psz, CCHMAX(dbgZoneParm.pszModule));
  212. // Copy the zone names
  213. for (i = 0; i < cZones; i++)
  214. {
  215. lstrcpynA(dbgZoneParm.szZoneNames[i], psz[1+i], CCHMAX(dbgZoneParm.szZoneNames[0]));
  216. }
  217. // Get the detault zone settings
  218. {
  219. RegEntry reZones(ZONES_KEY, HKEY_LOCAL_MACHINE);
  220. dbgZoneParm.ulZoneMask = reZones.GetNumber(CUSTRING(dbgZoneParm.pszModule), ulZoneDefault);
  221. }
  222. hDbgZone = NmDbgCreateZone(dbgZoneParm.pszModule);
  223. if (NULL == hDbgZone)
  224. {
  225. OutputDebugStringA("DbgInit: Failed to create zones!\r\n");
  226. return;
  227. }
  228. NmDbgSetZone(hDbgZone, &dbgZoneParm);
  229. *phDbgZone = hDbgZone;
  230. }
  231. VOID NMINTERNAL DbgDeInit(HDBGZONE * phDbgZone)
  232. {
  233. if (NULL == phDbgZone)
  234. return;
  235. if (NULL == *phDbgZone)
  236. return;
  237. //DbgMsg("Freeing Zone [%s]",((PZONEINFO)(*phDbgZone))->pszModule);
  238. NmDbgDeleteZone("", *phDbgZone);
  239. *phDbgZone = NULL;
  240. if( 0 == InterlockedDecrement( &_gLockCount ) )
  241. {
  242. UnMapDebugZoneArea();
  243. if( _ghMutexFile )
  244. {
  245. CloseHandle( _ghMutexFile );
  246. _ghMutexFile = NULL;
  247. }
  248. if( _ghDbgZoneMutex )
  249. {
  250. CloseHandle( _ghDbgZoneMutex );
  251. _ghDbgZoneMutex = NULL;
  252. }
  253. }
  254. }
  255. //////////////////////////////////////////////////////////////////////////////////
  256. // from dbgzone.cpp
  257. /***************************************************************************
  258. Name : NmDbgCreateZones
  259. Purpose : A module calls this to allocate/initialize the zone area for debugging
  260. purposes.
  261. Parameters: pszName - the name of the module
  262. Returns :
  263. Comment :
  264. ***************************************************************************/
  265. HDBGZONE WINAPI NmDbgCreateZone(LPSTR pszName)
  266. {
  267. PZONEINFO pZoneInfo=NULL;
  268. if (!(pZoneInfo = FindZoneForModule(pszName)))
  269. pZoneInfo = AllocZoneForModule(pszName);
  270. return ((HDBGZONE)pZoneInfo);
  271. }
  272. /***************************************************************************
  273. Name : NmDbgDeleteZones
  274. Purpose :
  275. Parameters:
  276. Returns :
  277. Comment :
  278. ***************************************************************************/
  279. void WINAPI NmDbgDeleteZone(LPSTR pszName, HDBGZONE hDbgZone)
  280. {
  281. //decrement reference count
  282. PZONEINFO pZoneInfo = (PZONEINFO)hDbgZone;
  283. ASSERT( _ghDbgZoneMutex );
  284. ACQMUTEX(_ghDbgZoneMutex);
  285. if (pZoneInfo)
  286. {
  287. pZoneInfo->ulRefCnt--;
  288. if (pZoneInfo->ulRefCnt == 0)
  289. {
  290. pZoneInfo->bInUse = FALSE;
  291. pZoneInfo->ulSignature = 0;
  292. }
  293. }
  294. RELMUTEX(_ghDbgZoneMutex);
  295. }
  296. /***************************************************************************
  297. Name : NmDbgSetZones
  298. Purpose :
  299. Parameters:
  300. Returns :
  301. Comment :
  302. ***************************************************************************/
  303. BOOL WINAPI NmDbgSetZone(HDBGZONE hDbgZone, PDBGZONEINFO pZoneParam)
  304. {
  305. PZONEINFO pZoneInfo = (PZONEINFO)hDbgZone;
  306. if (!pZoneInfo)
  307. return FALSE;
  308. if (lstrcmpA(pZoneInfo->pszModule,pZoneParam->pszModule))
  309. return FALSE;
  310. pZoneInfo->ulZoneMask = pZoneParam->ulZoneMask;
  311. CopyMemory(pZoneInfo->szZoneNames, pZoneParam->szZoneNames,
  312. (sizeof(CHAR) * MAXNUM_OF_ZONES * MAXSIZE_OF_ZONENAME));
  313. return(TRUE);
  314. }
  315. /***************************************************************************
  316. Name : NmDbgGetZoneParams
  317. Purpose :
  318. Parameters:
  319. Returns :
  320. Comment :
  321. ***************************************************************************/
  322. BOOL WINAPI NmDbgGetAllZoneParams(PDBGZONEINFO *plpZoneParam,LPUINT puCnt)
  323. {
  324. UINT ui;
  325. PZONEINFO pCurZone;
  326. if ((NULL == plpZoneParam) || (NULL == puCnt))
  327. return FALSE;
  328. ACQMUTEX(_ghDbgZoneMutex);
  329. *puCnt = 0;
  330. for (pCurZone = _gprgZoneInfo, ui=0;
  331. ui<MAXNUM_OF_MODULES && pCurZone!=NULL;
  332. ui++,pCurZone++)
  333. {
  334. if ((pCurZone->bInUse) && (pCurZone->ulSignature == ZONEINFO_SIGN))
  335. {
  336. (*puCnt)++;
  337. }
  338. }
  339. *plpZoneParam = _gprgZoneInfo;
  340. RELMUTEX(_ghDbgZoneMutex);
  341. return TRUE;
  342. }
  343. BOOL WINAPI NmDbgFreeZoneParams(PDBGZONEINFO pZoneParam)
  344. {
  345. return TRUE;
  346. }
  347. PZONEINFO NMINTERNAL FindZoneForModule(LPCSTR pszModule)
  348. {
  349. int i;
  350. PZONEINFO pCurZone;
  351. for (pCurZone = _gprgZoneInfo,i=0;i<MAXNUM_OF_MODULES && pCurZone!=NULL;i++,pCurZone++)
  352. {
  353. if ((pCurZone->bInUse) && (pCurZone->ulSignature == ZONEINFO_SIGN)
  354. && (!lstrcmpA(pCurZone->pszModule,pszModule)))
  355. {
  356. ACQMUTEX(_ghDbgZoneMutex);
  357. pCurZone->ulRefCnt++;
  358. RELMUTEX(_ghDbgZoneMutex);
  359. return pCurZone;
  360. }
  361. }
  362. return NULL;
  363. }
  364. /***************************************************************************
  365. Name : AllocZoneForModule
  366. Purpose : Allocates the
  367. Parameters:
  368. Returns :
  369. Comment :
  370. ***************************************************************************/
  371. PZONEINFO NMINTERNAL AllocZoneForModule(LPCSTR pszModule)
  372. {
  373. int i;
  374. PZONEINFO pCurZone;
  375. PZONEINFO pZoneForMod=NULL;
  376. ACQMUTEX(_ghDbgZoneMutex);
  377. for (pCurZone = _gprgZoneInfo,i=0;
  378. (i<MAXNUM_OF_MODULES && pCurZone!=NULL);
  379. i++,pCurZone++)
  380. {
  381. if (!(pCurZone->bInUse))
  382. {
  383. pCurZone->bInUse = TRUE;
  384. pCurZone->ulSignature = ZONEINFO_SIGN;
  385. pCurZone->ulRefCnt = 1;
  386. lstrcpyA(pCurZone->pszModule, pszModule);
  387. pZoneForMod = pCurZone;
  388. break;
  389. }
  390. }
  391. RELMUTEX(_ghDbgZoneMutex);
  392. return(pZoneForMod);
  393. }
  394. VOID NMINTERNAL SetDbgFlags(void)
  395. {
  396. PTSTR psz;
  397. RegEntry reDebug(DEBUG_KEY, HKEY_LOCAL_MACHINE);
  398. _gpDbg->fOutputDebugString = reDebug.GetNumber(REGVAL_DBG_OUTPUT, DEFAULT_DBG_OUTPUT);
  399. _gpDbg->fWinOutput = reDebug.GetNumber(REGVAL_DBG_WIN_OUTPUT, DEFAULT_DBG_NO_WIN);
  400. _gpDbg->fFileOutput = reDebug.GetNumber(REGVAL_DBG_FILE_OUTPUT, DEFAULT_DBG_NO_FILE);
  401. _gpDbg->uShowTime = reDebug.GetNumber(REGVAL_DBG_SHOW_TIME, DBG_FMTTIME_NONE);
  402. _gpDbg->fShowThreadId = reDebug.GetNumber(REGVAL_DBG_SHOW_THREADID, 0);
  403. _gpDbg->fShowModule = reDebug.GetNumber(REGVAL_DBG_SHOW_MODULE, 0);
  404. psz = reDebug.GetString(REGVAL_DBG_FILE);
  405. if (0 != lstrlen(psz))
  406. {
  407. lstrcpyA(_gpDbg->szFile, CUSTRING(psz));
  408. }
  409. else
  410. {
  411. UINT cchFile;
  412. cchFile = GetWindowsDirectoryA(_gpDbg->szFile, CCHMAX(_gpDbg->szFile));
  413. _gpDbg->szFile[cchFile++] = '\\';
  414. lstrcpyA(_gpDbg->szFile + cchFile, CUSTRING(DEFAULT_DBG_FILENAME));
  415. }
  416. }
  417. VOID InitZoneMmf(PZONEINFO prgZoneInfo)
  418. {
  419. ZeroMemory(prgZoneInfo, CBMMFDBG);
  420. SetDbgFlags();
  421. }
  422. PZONEINFO NMINTERNAL MapDebugZoneArea(void)
  423. {
  424. PZONEINFO prgZoneInfo = NULL;
  425. BOOL fCreated;
  426. PSECURITY_DESCRIPTOR sd = NULL;
  427. SECURITY_ATTRIBUTES sa;
  428. // Obtain a true NULL security descriptor (so if running as a service, user processes can access it)
  429. // InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
  430. // SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); // NULL DACL = wide open
  431. sd = CreateSd();
  432. FillMemory(&sa, sizeof(sa), 0);
  433. sa.nLength = sizeof(sa);
  434. sa.lpSecurityDescriptor = sd;
  435. //create a memory mapped object that is backed by paging file
  436. _ghDbgZoneMap = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE,
  437. 0, CBMMFDBG, SZ_DBG_MAPPED_ZONE);
  438. if (_ghDbgZoneMap)
  439. {
  440. fCreated = (0 == GetLastError());
  441. prgZoneInfo = (PZONEINFO) MapViewOfFile(_ghDbgZoneMap, FILE_MAP_READ|FILE_MAP_WRITE, 0,0,0);
  442. if (NULL != prgZoneInfo)
  443. {
  444. // Grab pointer to shared data area
  445. _gpDbg = (PNMDBG) (((PBYTE) prgZoneInfo) + (MAXNUM_OF_MODULES * sizeof(ZONEINFO)));
  446. if (fCreated)
  447. InitZoneMmf(prgZoneInfo);
  448. }
  449. }
  450. if(sd)
  451. {
  452. HeapFree(GetProcessHeap(), 0, sd);
  453. }
  454. return prgZoneInfo;
  455. }
  456. VOID NMINTERNAL UnMapDebugZoneArea(void)
  457. {
  458. if (_gprgZoneInfo)
  459. {
  460. UnmapViewOfFile(_gprgZoneInfo);
  461. _gprgZoneInfo = NULL;
  462. }
  463. ClosePh(&_ghDbgZoneMap);
  464. }
  465. VOID NMINTERNAL InitDbgZone(void)
  466. {
  467. if (NULL != _gprgZoneInfo)
  468. return; // already initialized
  469. _gprgZoneInfo = MapDebugZoneArea();
  470. // Create log file data
  471. PSECURITY_DESCRIPTOR sd = NULL;
  472. SECURITY_ATTRIBUTES sa;
  473. // Obtain a true NULL security descriptor (so if running as a service, user processes can access it)
  474. // InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
  475. // SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); // NULL DACL = wide open
  476. sd = CreateSd();
  477. FillMemory(&sa, sizeof(sa), 0);
  478. sa.nLength = sizeof(sa);
  479. sa.lpSecurityDescriptor = sd;
  480. _ghMutexFile = CreateMutex(&sa, FALSE, SZ_DBG_FILE_MUTEX);
  481. _ghDbgZoneMutex = CreateMutex(&sa, FALSE, SZ_DBG_ZONE_MUTEX);
  482. if (_gpDbg != NULL && _gpDbg->fFileOutput)
  483. {
  484. HANDLE hFile;
  485. DWORD dw;
  486. CHAR sz[MAX_PATH];
  487. SYSTEMTIME systime;
  488. hFile = CreateFileA(_gpDbg->szFile,
  489. GENERIC_WRITE | GENERIC_WRITE, 0, &sa,
  490. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  491. if (INVALID_HANDLE_VALUE == hFile)
  492. {
  493. _gpDbg->fFileOutput = FALSE;
  494. goto cleanup;
  495. }
  496. GetLocalTime(&systime);
  497. wsprintfA(sz,
  498. "\r\n======== TRACE Started: %hu/%hu/%hu (%hu:%hu)\r\n",
  499. systime.wMonth, systime.wDay, systime.wYear, systime.wHour, systime.wMinute);
  500. SetFilePointer(hFile, 0, NULL, FILE_END);
  501. WriteFile(hFile, sz, lstrlenA(sz), &dw, NULL);
  502. CloseHandle(hFile);
  503. }
  504. cleanup:
  505. if (sd)
  506. {
  507. HeapFree(GetProcessHeap(), 0, sd);
  508. }
  509. }
  510. ///////////////////////////////////////
  511. // Routines for controlling debug output
  512. BOOL WINAPI NmDbgRegisterCtl(HWND hwnd, UINT uDisplayMsg)
  513. {
  514. if ((NULL == _gpDbg) || (NULL != _gpDbg->hwndCtrl))
  515. return FALSE;
  516. _gpDbg->msgDisplay = uDisplayMsg;
  517. _gpDbg->hwndCtrl = hwnd;
  518. return TRUE;
  519. }
  520. BOOL WINAPI NmDbgDeregisterCtl(HWND hwnd)
  521. {
  522. if ((NULL == _gpDbg) || (hwnd != _gpDbg->hwndCtrl))
  523. return FALSE;
  524. _gpDbg->hwndCtrl = NULL;
  525. _gpDbg->msgDisplay = 0;
  526. return TRUE;
  527. }
  528. BOOL WINAPI NmDbgSetLoggingOptions(HWND hwnd, UINT uOptions)
  529. {
  530. return FALSE;
  531. }
  532. PNMDBG WINAPI GetPNmDbg(void)
  533. {
  534. return _gpDbg;
  535. }
  536. VOID WINAPI NmDbgSetZoneFileName(HDBGZONE hZone, LPCSTR pszFile)
  537. {
  538. PSTR pszZoneFile;
  539. if (IsBadWritePtr((PVOID) hZone, sizeof(ZONEINFO)))
  540. return;
  541. if (((PZONEINFO) hZone)->ulSignature != ZONEINFO_SIGN)
  542. return;
  543. pszZoneFile = &(((PZONEINFO) hZone)->szFile[0]);
  544. if (NULL == pszFile)
  545. {
  546. *pszZoneFile = '\0';
  547. }
  548. else
  549. {
  550. lstrcpynA(pszZoneFile, pszFile, CCHMAX(((PZONEINFO) hZone)->szFile));
  551. }
  552. }
  553. /* D B G C U R R E N T T I M E */
  554. /*-------------------------------------------------------------------------
  555. %%Function: DbgCurrentTime
  556. Format the current time
  557. -------------------------------------------------------------------------*/
  558. VOID DbgCurrentTime(PCHAR psz)
  559. {
  560. if (DBG_FMTTIME_TICK == _gpDbg->uShowTime)
  561. {
  562. wsprintfA(psz, "[%04X] ", GetTickCount());
  563. }
  564. else
  565. {
  566. SYSTEMTIME sysTime;
  567. GetLocalTime(&sysTime);
  568. switch (_gpDbg->uShowTime)
  569. {
  570. default:
  571. case DBG_FMTTIME_FULL:
  572. wsprintfA(psz, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] ",
  573. sysTime.wYear, sysTime.wMonth, sysTime.wDay,
  574. sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
  575. break;
  576. case DBG_FMTTIME_DAY:
  577. wsprintfA(psz, "[%02d:%02d:%02d.%03d] ",
  578. sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
  579. break;
  580. }
  581. }
  582. }
  583. /* P S Z P R I N T F */
  584. /*-------------------------------------------------------------------------
  585. %%Function: PszPrintf
  586. Utility function to wsprintf a string for debug.
  587. -------------------------------------------------------------------------*/
  588. PSTR PszPrintf(PCSTR pszFormat,...)
  589. {
  590. PSTR psz = (PSTR) LocalAlloc(LMEM_FIXED, MAX_PATH);
  591. if (NULL != psz)
  592. {
  593. va_list v1;
  594. va_start(v1, pszFormat);
  595. wvsprintfA(psz, pszFormat, v1);
  596. va_end(v1);
  597. }
  598. return psz;
  599. }
  600. /* D E B U G T R A P F N */
  601. /*-------------------------------------------------------------------------
  602. %%Function: DebugTrapFn
  603. -------------------------------------------------------------------------*/
  604. VOID NMINTERNAL DebugTrapFn(VOID)
  605. {
  606. _DbgBreak();
  607. }
  608. VOID DebugPrintfTraceMem(LPCSTR pszFormat,...)
  609. {
  610. // DO NOTHING
  611. va_list arglist;
  612. va_start(arglist, pszFormat);
  613. va_end(arglist);
  614. }
  615. #endif /* NM_DEBUG - almost the whole file */
  616. /*************************************************************************/
  617. const int RPF_UNKNOWN = 0;
  618. const int RPF_ENABLED = 1;
  619. const int RPF_DISABLED = 2;
  620. static int gRpf = RPF_UNKNOWN;
  621. static TCHAR gszRetailOutputFilename[MAX_PATH]; // retail trace filename
  622. /* F E N A B L E D R E T A I L P R I N T F */
  623. /*-------------------------------------------------------------------------
  624. %%Function: FEnabledRetailPrintf
  625. Return TRUE if retail output is enabled.
  626. -------------------------------------------------------------------------*/
  627. BOOL FEnabledRetailPrintf(VOID)
  628. {
  629. if (RPF_UNKNOWN == gRpf)
  630. {
  631. RegEntry reDebug(DEBUG_KEY, HKEY_LOCAL_MACHINE);
  632. gRpf = reDebug.GetNumber(REGVAL_RETAIL_LOG, RPF_DISABLED);
  633. if ((RPF_ENABLED != gRpf) ||
  634. (!GetInstallDirectory(gszRetailOutputFilename)) )
  635. {
  636. gRpf = RPF_DISABLED;
  637. }
  638. else
  639. {
  640. lstrcat(gszRetailOutputFilename, RETAIL_LOG_FILENAME);
  641. }
  642. }
  643. return (RPF_ENABLED == gRpf);
  644. }
  645. /* R E T A I L P R I N T F T R A C E */
  646. /*-------------------------------------------------------------------------
  647. %%Function: RetailPrintfTrace
  648. Print retail information to a file
  649. -------------------------------------------------------------------------*/
  650. VOID WINAPI RetailPrintfTrace(LPCSTR pszFormat,...)
  651. {
  652. HANDLE hFile;
  653. va_list v1;
  654. CHAR szOutput[1024];
  655. if (!FEnabledRetailPrintf())
  656. return; // Retail output is disabled
  657. va_start(v1, pszFormat);
  658. #ifdef DEBUG
  659. // Also use normal output mechanism for debug builds
  660. _DbgPrintf(NULL, "Retail:PrintfTrace", pszFormat, v1);
  661. #endif
  662. wvsprintfA(szOutput, pszFormat, v1);
  663. // Always append the CRLF
  664. ASSERT(lstrlenA(szOutput) < (CCHMAX(szOutput)-2));
  665. lstrcatA(szOutput, "\r\n");
  666. // open a log file for appending. create if does not exist
  667. hFile = CreateFile(gszRetailOutputFilename, GENERIC_WRITE,
  668. 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
  669. if (hFile != INVALID_HANDLE_VALUE)
  670. {
  671. // seek to end of file
  672. DWORD dw = SetFilePointer(hFile, 0, NULL, FILE_END);
  673. WriteFile(hFile, szOutput, lstrlenA(szOutput), &dw, NULL);
  674. CloseHandle(hFile);
  675. }
  676. va_end(v1);
  677. }
  678. //
  679. // CreateSids
  680. //
  681. // Create 3 Security IDs
  682. //
  683. // Caller must free memory allocated to SIDs on success.
  684. //
  685. // Returns: TRUE if successfull, FALSE if not.
  686. //
  687. BOOL
  688. CreateSids(
  689. PSID *BuiltInAdministrators,
  690. PSID *PowerUsers,
  691. PSID *AuthenticatedUsers
  692. )
  693. {
  694. //
  695. // An SID is built from an Identifier Authority and a set of Relative IDs
  696. // (RIDs). The Authority of interest to us SECURITY_NT_AUTHORITY.
  697. //
  698. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  699. //
  700. // Each RID represents a sub-unit of the authority. Two of the SIDs we
  701. // want to build, Local Administrators, and Power Users, are in the "built
  702. // in" domain. The other SID, for Authenticated users, is based directly
  703. // off of the authority.
  704. //
  705. // For examples of other useful SIDs consult the list in
  706. // \nt\public\sdk\inc\ntseapi.h.
  707. //
  708. if (!AllocateAndInitializeSid(&NtAuthority,
  709. 2, // 2 sub-authorities
  710. SECURITY_BUILTIN_DOMAIN_RID,
  711. DOMAIN_ALIAS_RID_ADMINS,
  712. 0,0,0,0,0,0,
  713. BuiltInAdministrators)) {
  714. // error
  715. } else if (!AllocateAndInitializeSid(&NtAuthority,
  716. 2, // 2 sub-authorities
  717. SECURITY_BUILTIN_DOMAIN_RID,
  718. DOMAIN_ALIAS_RID_POWER_USERS,
  719. 0,0,0,0,0,0,
  720. PowerUsers)) {
  721. // error
  722. FreeSid(*BuiltInAdministrators);
  723. *BuiltInAdministrators = NULL;
  724. } else if (!AllocateAndInitializeSid(&NtAuthority,
  725. 1, // 1 sub-authority
  726. SECURITY_AUTHENTICATED_USER_RID,
  727. 0,0,0,0,0,0,0,
  728. AuthenticatedUsers)) {
  729. // error
  730. FreeSid(*BuiltInAdministrators);
  731. *BuiltInAdministrators = NULL;
  732. FreeSid(*PowerUsers);
  733. *PowerUsers = NULL;
  734. } else {
  735. return TRUE;
  736. }
  737. return FALSE;
  738. }
  739. //
  740. // CreateSd
  741. //
  742. // Creates a SECURITY_DESCRIPTOR with specific DACLs. Modify the code to
  743. // change.
  744. //
  745. // Caller must free the returned buffer if not NULL.
  746. //
  747. PSECURITY_DESCRIPTOR
  748. CreateSd(
  749. VOID
  750. )
  751. {
  752. PSID AuthenticatedUsers;
  753. PSID BuiltInAdministrators;
  754. PSID PowerUsers;
  755. if (!CreateSids(&BuiltInAdministrators,
  756. &PowerUsers,
  757. &AuthenticatedUsers)) {
  758. // error
  759. } else {
  760. //
  761. // Calculate the size of and allocate a buffer for the DACL, we need
  762. // this value independently of the total alloc size for ACL init.
  763. //
  764. PSECURITY_DESCRIPTOR Sd = NULL;
  765. ULONG AclSize;
  766. //
  767. // "- sizeof (ULONG)" represents the SidStart field of the
  768. // ACCESS_ALLOWED_ACE. Since we're adding the entire length of the
  769. // SID, this field is counted twice.
  770. //
  771. AclSize = sizeof (ACL) +
  772. (3 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG))) +
  773. GetLengthSid(AuthenticatedUsers) +
  774. GetLengthSid(BuiltInAdministrators) +
  775. GetLengthSid(PowerUsers);
  776. Sd = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH + AclSize);
  777. if (!Sd) {
  778. // error
  779. } else {
  780. ACL *Acl;
  781. Acl = (ACL *)((BYTE *)Sd + SECURITY_DESCRIPTOR_MIN_LENGTH);
  782. if (!InitializeAcl(Acl,
  783. AclSize,
  784. ACL_REVISION)) {
  785. // error
  786. } else if (!AddAccessAllowedAce(Acl,
  787. ACL_REVISION,
  788. SYNCHRONIZE | GENERIC_READ,
  789. AuthenticatedUsers)) {
  790. // Failed to build the ACE granting "Authenticated users"
  791. // (SYNCHRONIZE | GENERIC_READ) access.
  792. } else if (!AddAccessAllowedAce(Acl,
  793. ACL_REVISION,
  794. SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE,
  795. PowerUsers)) {
  796. // Failed to build the ACE granting "Power users"
  797. // (SYNCHRONIZE | GENERIC_READ | GENERIC_WRITE) access.
  798. } else if (!AddAccessAllowedAce(Acl,
  799. ACL_REVISION,
  800. GENERIC_ALL,
  801. BuiltInAdministrators)) {
  802. // Failed to build the ACE granting "Built-in Administrators"
  803. // GENERIC_ALL access.
  804. } else if (!InitializeSecurityDescriptor(Sd,
  805. SECURITY_DESCRIPTOR_REVISION)) {
  806. // error
  807. } else if (!SetSecurityDescriptorDacl(Sd,
  808. TRUE,
  809. Acl,
  810. FALSE)) {
  811. // error
  812. } else {
  813. FreeSid(AuthenticatedUsers);
  814. FreeSid(BuiltInAdministrators);
  815. FreeSid(PowerUsers);
  816. return Sd;
  817. }
  818. HeapFree(GetProcessHeap(), 0, Sd);
  819. }
  820. FreeSid(AuthenticatedUsers);
  821. FreeSid(BuiltInAdministrators);
  822. FreeSid(PowerUsers);
  823. }
  824. return NULL;
  825. }