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.

605 lines
18 KiB

  1. /********************************************************************
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. pfrutil.h
  5. Abstract:
  6. PFR utility stuff
  7. Revision History:
  8. DerekM created 05/01/99
  9. ********************************************************************/
  10. #ifndef PFRUTIL_H
  11. #define PFRUTIL_H
  12. typedef ULONG foo;
  13. #define GUI_MODE_SETUP 1
  14. // make sure both _DEBUG & DEBUG are defined if one is defined. Otherwise
  15. // the ASSERT macro never does anything
  16. #if defined(_DEBUG) && !defined(DEBUG)
  17. #define DEBUG 1
  18. #endif
  19. #if defined(DEBUG) && !defined(_DEBUG)
  20. #define _DEBUG 1
  21. #endif
  22. #include "dbgtrace.h"
  23. ////////////////////////////////////////////////////////////////////////////
  24. // tracing wrappers
  25. // can't call HRESULT_FROM_WIN32 with a fn as a parameter cuz it is a macro
  26. // and evaluates the expression 3 times. This is a particularlly bad thing
  27. // when u don't look at macros first to see what they do.
  28. inline HRESULT ChangeErrToHR(DWORD dwErr) { return HRESULT_FROM_WIN32(dwErr); }
  29. #if defined(NOTRACE)
  30. #define INIT_TRACING
  31. #define TERM_TRACING
  32. #define USE_TRACING(sz)
  33. #define DBG_MSG(sz)
  34. #define TESTHR(hr, fn) \
  35. hr = (fn);
  36. #define TESTBOOL(hr, fn) \
  37. hr = ((fn) ? NOERROR : HRESULT_FROM_WIN32(GetLastError()));
  38. #define TESTERR(hr, fn) \
  39. SetLastError((fn)); \
  40. hr = HRESULT_FROM_WIN32(GetLastError());
  41. #define VALIDATEPARM(hr, expr) \
  42. hr = ((expr) ? E_INVALIDARG : NOERROR);
  43. #define VALIDATEEXPR(hr, expr, hrErr) \
  44. hr = ((expr) ? (hrErr) : NOERROR);
  45. #else
  46. #define INIT_TRACING \
  47. InitAsyncTrace();
  48. #define TERM_TRACING \
  49. TermAsyncTrace();
  50. #define USE_TRACING(sz) \
  51. TraceQuietEnter(sz); \
  52. TraceFunctEntry(sz); \
  53. DWORD __dwtraceGLE = GetLastError(); \
  54. #define DBG_MSG(sz) \
  55. ErrorTrace(0, sz)
  56. #define TESTHR(hr, fn) \
  57. if (FAILED(hr = (fn))) \
  58. { \
  59. __dwtraceGLE = GetLastError(); \
  60. ErrorTrace(0, "%s failed. Err: 0x%08x", #fn, hr); \
  61. SetLastError(__dwtraceGLE); \
  62. } \
  63. #define TESTBOOL(hr, fn) \
  64. hr = NOERROR; \
  65. if ((fn) == FALSE) \
  66. { \
  67. __dwtraceGLE = GetLastError(); \
  68. hr = HRESULT_FROM_WIN32(__dwtraceGLE); \
  69. ErrorTrace(0, "%s failed. Err: 0x%08x", #fn, __dwtraceGLE); \
  70. SetLastError(__dwtraceGLE); \
  71. }
  72. #define TESTERR(hr, fn) \
  73. SetLastError((fn)); \
  74. if (FAILED(hr = HRESULT_FROM_WIN32(GetLastError()))) \
  75. { \
  76. __dwtraceGLE = GetLastError(); \
  77. ErrorTrace(0, "%s failed. Err: %d", #fn, __dwtraceGLE); \
  78. SetLastError(__dwtraceGLE); \
  79. }
  80. #define VALIDATEPARM(hr, expr) \
  81. if (expr) \
  82. { \
  83. ErrorTrace(0, "Invalid parameters passed to %s", \
  84. ___pszFunctionName); \
  85. SetLastError(ERROR_INVALID_PARAMETER); \
  86. hr = E_INVALIDARG; \
  87. } \
  88. else hr = NOERROR;
  89. #define VALIDATEEXPR(hr, expr, hrErr) \
  90. if (expr) \
  91. { \
  92. ErrorTrace(0, "Expression failure %s", #expr); \
  93. hr = (hrErr); \
  94. } \
  95. else hr = NOERROR;
  96. #endif
  97. ////////////////////////////////////////////////////////////////////////////
  98. // Memory
  99. #if defined(DEBUG) || defined(_DEBUG)
  100. // this structure must ALWAYS be 8 byte aligned. Add padding to the end if
  101. // it isn't.
  102. struct SMyMemDebug
  103. {
  104. __int64 hHeap;
  105. __int64 cb;
  106. DWORD dwTag;
  107. DWORD dwChk;
  108. };
  109. #endif
  110. extern HANDLE g_hPFPrivateHeap;
  111. // **************************************************************************
  112. inline HANDLE MyHeapCreate(SIZE_T cbInitial = 8192, SIZE_T cbMax = 0)
  113. {
  114. return HeapCreate(0, cbInitial, cbMax);
  115. }
  116. // **************************************************************************
  117. inline BOOL MyHeapDestroy(HANDLE hHeap)
  118. {
  119. return HeapDestroy(hHeap);
  120. }
  121. // **************************************************************************
  122. inline LPVOID MyAlloc(SIZE_T cb, HANDLE hHeap = NULL, BOOL fZero = TRUE)
  123. {
  124. #if defined(DEBUG) || defined(_DEBUG)
  125. SMyMemDebug *psmmd;
  126. LPBYTE pb;
  127. cb += (sizeof(SMyMemDebug) + 4);
  128. hHeap = (hHeap != NULL) ? hHeap : GetProcessHeap();
  129. pb = (LPBYTE)HeapAlloc(hHeap, ((fZero) ? HEAP_ZERO_MEMORY : 0), cb);
  130. if (pb != NULL)
  131. {
  132. psmmd = (SMyMemDebug *)pb;
  133. psmmd->hHeap = (__int64)hHeap;
  134. psmmd->cb = (__int64)cb;
  135. psmmd->dwTag = 0xBCBCBCBC;
  136. psmmd->dwChk = 0xBCBCBCBC;
  137. // do this cuz it's easier than figuring out the alignment and
  138. // manually converting it to a 4 byte aligned value
  139. *(pb + cb - 4) = 0xBC;
  140. *(pb + cb - 3) = 0xBC;
  141. *(pb + cb - 2) = 0xBC;
  142. *(pb + cb - 1) = 0xBC;
  143. pb = (PBYTE)pb + sizeof(SMyMemDebug);
  144. }
  145. return pb;
  146. #else
  147. return HeapAlloc(((hHeap != NULL) ? hHeap : GetProcessHeap()),
  148. ((fZero) ? HEAP_ZERO_MEMORY : 0), cb);
  149. #endif
  150. }
  151. // **************************************************************************
  152. inline LPVOID MyReAlloc(LPVOID pv, SIZE_T cb, HANDLE hHeap = NULL,
  153. BOOL fZero = TRUE)
  154. {
  155. #if defined(DEBUG) || defined(_DEBUG)
  156. SMyMemDebug *psmmd;
  157. SIZE_T cbOld;
  158. LPBYTE pbNew;
  159. LPBYTE pb = (LPBYTE)pv;
  160. // if this is NULL, force a call to HeapReAlloc so that it can set the
  161. // proper error for GLE to fetch
  162. if (pv == NULL)
  163. {
  164. SetLastError(0);
  165. return NULL;
  166. }
  167. pb -= sizeof(SMyMemDebug);
  168. hHeap = (hHeap != NULL) ? hHeap : GetProcessHeap();
  169. // wrap this in a try block in case the memory was not allocated
  170. // by us or is corrupted- in which case the following could
  171. // cause an AV.
  172. __try
  173. {
  174. psmmd = (SMyMemDebug *)pb;
  175. cbOld = (SIZE_T)psmmd->cb;
  176. _ASSERT(psmmd->hHeap == (__int64)hHeap);
  177. _ASSERT(psmmd->dwTag == 0xBCBCBCBC);
  178. _ASSERT(psmmd->dwChk == 0xBCBCBCBC);
  179. // do this cuz it's easier than figuring out the alignment and
  180. // manually converting it to a 4 byte aligned value
  181. _ASSERT(*(pb + cbOld - 4) == 0xBC);
  182. _ASSERT(*(pb + cbOld - 3) == 0xBC);
  183. _ASSERT(*(pb + cbOld - 2) == 0xBC);
  184. _ASSERT(*(pb + cbOld - 1) == 0xBC);
  185. if (psmmd->hHeap != (__int64)hHeap)
  186. hHeap = (HANDLE)(DWORD_PTR)psmmd->hHeap;
  187. }
  188. __except(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  189. {
  190. _ASSERT(FALSE);
  191. }
  192. hHeap = *((HANDLE *)pb);
  193. cb += (sizeof(SMyMemDebug) + 4);
  194. pbNew = (LPBYTE)HeapReAlloc(hHeap, ((fZero) ? HEAP_ZERO_MEMORY : 0), pb, cb);
  195. if (pbNew != NULL)
  196. {
  197. psmmd = (SMyMemDebug *)pb;
  198. psmmd->hHeap = (__int64)hHeap;
  199. psmmd->cb = (__int64)cb;
  200. psmmd->dwTag = 0xBCBCBCBC;
  201. psmmd->dwChk = 0xBCBCBCBC;
  202. // do this cuz it's easier than figuring out the alignment and
  203. // manually converting it to a 4 byte aligned value
  204. *(pb + cb - 4) = 0xBC;
  205. *(pb + cb - 3) = 0xBC;
  206. *(pb + cb - 2) = 0xBC;
  207. *(pb + cb - 1) = 0xBC;
  208. pb = (PBYTE)pb + sizeof(SMyMemDebug);
  209. }
  210. return pv;
  211. #else
  212. return HeapReAlloc(((hHeap != NULL) ? hHeap : GetProcessHeap()),
  213. ((fZero) ? HEAP_ZERO_MEMORY : 0), pv, cb);
  214. #endif
  215. }
  216. // **************************************************************************
  217. inline BOOL MyFree(LPVOID pv, HANDLE hHeap = NULL)
  218. {
  219. #if defined(DEBUG) || defined(_DEBUG)
  220. SMyMemDebug *psmmd;
  221. SIZE_T cbOld;
  222. LPBYTE pb = (LPBYTE)pv;
  223. // if this is NULL, force a call to HeapFree so that it can set the
  224. // proper error for GLE to fetch
  225. if (pv == NULL)
  226. return TRUE;
  227. pb -= sizeof(SMyMemDebug);
  228. hHeap = (hHeap != NULL) ? hHeap : GetProcessHeap();
  229. // wrap this in a try block in case the memory was not allocated
  230. // by us or is corrupted- in which case the following could
  231. // cause an AV.
  232. __try
  233. {
  234. psmmd = (SMyMemDebug *)pb;
  235. cbOld = (SIZE_T)psmmd->cb;
  236. _ASSERT(psmmd->hHeap == (__int64)hHeap);
  237. _ASSERT(psmmd->dwTag == 0xBCBCBCBC);
  238. _ASSERT(psmmd->dwChk == 0xBCBCBCBC);
  239. // do this cuz it's easier than figuring out the alignment and
  240. // manually converting it to a 4 byte aligned value
  241. _ASSERT(*(pb + cbOld - 4) == 0xBC);
  242. _ASSERT(*(pb + cbOld - 3) == 0xBC);
  243. _ASSERT(*(pb + cbOld - 2) == 0xBC);
  244. _ASSERT(*(pb + cbOld - 1) == 0xBC);
  245. if (psmmd->hHeap != (__int64)hHeap)
  246. {
  247. hHeap = (HANDLE)(DWORD_PTR)psmmd->hHeap;
  248. }
  249. }
  250. __except(EXCEPTION_ACCESS_VIOLATION == GetExceptionCode() ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
  251. {
  252. _ASSERT(FALSE);
  253. }
  254. FillMemory(pb, cbOld, 0xCB);
  255. return HeapFree(hHeap, 0, pb);
  256. #else
  257. return HeapFree(((hHeap != NULL) ? hHeap : GetProcessHeap()), 0, pv);
  258. #endif
  259. }
  260. ////////////////////////////////////////////////////////////////////////////
  261. // useful inlines / defines
  262. // **************************************************************************
  263. inline DWORD MyMax(DWORD a, DWORD b)
  264. {
  265. return (a > b) ? a : b;
  266. }
  267. // **************************************************************************
  268. inline DWORD MyMin(DWORD a, DWORD b)
  269. {
  270. return (a <= b) ? a : b;
  271. }
  272. #define Err2HR(dwErr) HRESULT_FROM_WIN32(dwErr)
  273. #define sizeofSTRW(wsz) sizeof(wsz) / sizeof(WCHAR)
  274. ////////////////////////////////////////////////////////////////////////////
  275. // Setup
  276. #define SIIP_NO_SETUP 0
  277. #define SIIP_GUI_SETUP 1
  278. #define SIIP_OOBE_SETUP 2
  279. DWORD SetupIsInProgress(void);
  280. ////////////////////////////////////////////////////////////////////////////
  281. // Files
  282. const WCHAR c_wszDirSuffix[] = L".dir00";
  283. HRESULT OpenFileMapped(LPWSTR wszFile, LPVOID *ppvFile, DWORD *pcbFile);
  284. HRESULT DeleteTempFile(LPWSTR wszFile);
  285. HRESULT MyCallNamedPipe(LPCWSTR wszPipe, LPVOID pvIn, DWORD cbIn,
  286. LPVOID pvOut, DWORD cbOut, DWORD *pcbRead,
  287. DWORD dwWaitPipe, DWORD dwWaitRead = INFINITE);
  288. DWORD CreateTempDirAndFile(LPCWSTR wszTempDir, LPCWSTR wszName,
  289. LPWSTR *pwszPath);
  290. BOOL DeleteTempDirAndFile(LPCWSTR wszPath, BOOL fFilePresent);
  291. BOOL DeleteFullAndTriageMiniDumps(LPCWSTR wszPath);
  292. ////////////////////////////////////////////////////////////////////////////
  293. // Security
  294. BOOL AllocSD(SECURITY_DESCRIPTOR *psd, DWORD dwOLs, DWORD dwAd, DWORD dwWA);
  295. void FreeSD(SECURITY_DESCRIPTOR *psd);
  296. BOOL IsUserAnAdmin(HANDLE hToken);
  297. ////////////////////////////////////////////////////////////////////////////
  298. // Registry
  299. enum EPFORK
  300. {
  301. orkWantWrite = 0x1,
  302. orkUseWOW64 = 0x2,
  303. };
  304. HRESULT OpenRegKey(HKEY hkeyMain, LPCWSTR wszSubKey, DWORD dwOpt, HKEY *phkey);
  305. HRESULT ReadRegEntry(HKEY hkey, LPCWSTR szValName, DWORD *pdwType,
  306. PBYTE pbBuffer, DWORD *pcbBuffer, PBYTE pbDefault,
  307. DWORD cbDefault);
  308. HRESULT ReadRegEntry(HKEY *rghkey, DWORD cKeys, LPCWSTR wszValName,
  309. DWORD *pdwType, PBYTE pbBuffer, DWORD *pcbBuffer,
  310. PBYTE pbDefault, DWORD cbDefault, DWORD *piKey = NULL);
  311. ////////////////////////////////////////////////////////////////////////////
  312. // version info
  313. #define APP_WINCOMP 0x1
  314. #define APP_MSAPP 0x2
  315. DWORD IsMicrosoftApp(LPWSTR wszAppPath, PBYTE pbAppInfo, DWORD cbAppInfo);
  316. ////////////////////////////////////////////////////////////////////////////
  317. // String
  318. WCHAR *MyStrStrIW(const WCHAR *wcs1, const WCHAR *wcs2);
  319. CHAR *MyStrStrIA(const CHAR *cs1, const CHAR *cs2);
  320. HRESULT MyURLEncode(LPWSTR wszDest, DWORD cchDest, LPWSTR wszSrc);
  321. ////////////////////////////////////////////////////////////////////////////
  322. // CPFGenericClassBase
  323. class CPFGenericClassBase
  324. {
  325. public:
  326. // CPFGenericClassBase(void) {}
  327. // virtual ~CPFGenericClassBase(void) {}
  328. void *operator new(size_t size)
  329. {
  330. return MyAlloc(size, NULL, FALSE);
  331. }
  332. void operator delete(void *pvMem)
  333. {
  334. if (pvMem != NULL)
  335. MyFree(pvMem, NULL);
  336. }
  337. };
  338. class CPFPrivHeapGenericClassBase
  339. {
  340. public:
  341. // CPFGenericClassBase(void) {}
  342. // virtual ~CPFGenericClassBase(void) {}
  343. void *operator new(size_t size)
  344. {
  345. return MyAlloc(size, g_hPFPrivateHeap, FALSE);
  346. }
  347. void operator delete(void *pvMem)
  348. {
  349. if (pvMem != NULL)
  350. MyFree(pvMem, g_hPFPrivateHeap);
  351. }
  352. };
  353. ////////////////////////////////////////////////////////////////////////////
  354. // CAutoUnlockCS
  355. // This class wrappers a critical section. It will automatically unlock the
  356. // CS when the class destructs (assuming it is locked)
  357. // NOTE: this object is intended to be used only as a local variable of a
  358. // function, not as a global variable or class member.
  359. class CAutoUnlockCS
  360. {
  361. private:
  362. #if defined(DEBUG) || defined(_DEBUG)
  363. DWORD m_dwOwningThread;
  364. #endif
  365. CRITICAL_SECTION *m_pcs;
  366. DWORD m_cLocks;
  367. public:
  368. CAutoUnlockCS(CRITICAL_SECTION *pcs, BOOL fTakeLock = FALSE)
  369. {
  370. m_pcs = pcs;
  371. m_cLocks = 0;
  372. #if defined(DEBUG) || defined(_DEBUG)
  373. m_dwOwningThread = 0;
  374. #endif
  375. if (fTakeLock)
  376. this->Lock();
  377. }
  378. ~CAutoUnlockCS(void)
  379. {
  380. _ASSERT(m_cLocks <= 1);
  381. if (m_pcs != NULL)
  382. {
  383. #if defined(DEBUG) || defined(_DEBUG)
  384. if (m_cLocks > 0)
  385. _ASSERT(m_dwOwningThread == GetCurrentThreadId());
  386. #endif
  387. while(m_cLocks > 0)
  388. {
  389. LeaveCriticalSection(m_pcs);
  390. m_cLocks--;
  391. }
  392. }
  393. }
  394. void Lock(void)
  395. {
  396. if (m_pcs != NULL)
  397. {
  398. EnterCriticalSection(m_pcs);
  399. m_cLocks++;
  400. #if defined(DEBUG) || defined(_DEBUG)
  401. m_dwOwningThread = GetCurrentThreadId();
  402. #endif
  403. }
  404. }
  405. void Unlock(void)
  406. {
  407. _ASSERT(m_cLocks > 0);
  408. _ASSERT(m_dwOwningThread == GetCurrentThreadId());
  409. if (m_pcs != NULL && m_cLocks > 0)
  410. {
  411. m_cLocks--;
  412. LeaveCriticalSection(m_pcs);
  413. }
  414. #if defined(DEBUG) || defined(_DEBUG)
  415. if (m_cLocks == 0)
  416. m_dwOwningThread = 0;
  417. #endif
  418. }
  419. };
  420. ////////////////////////////////////////////////////////////////////////////
  421. // CAutoUnlockMutex
  422. // This class wrappers a mutex. It will automatically unlock the
  423. // mutex when the class destructs (assuming it is owned)
  424. // NOTE: this object is intended to be used only as a local variable of a
  425. // function, not as a global variable or class member.
  426. class CAutoUnlockMutex
  427. {
  428. private:
  429. #if defined(DEBUG) || defined(_DEBUG)
  430. DWORD m_dwOwningThread;
  431. #endif
  432. HANDLE m_hmut;
  433. DWORD m_cLocks;
  434. public:
  435. CAutoUnlockMutex(HANDLE hmut, BOOL fTakeLock = FALSE)
  436. {
  437. m_hmut = hmut;
  438. m_cLocks = 0;
  439. #if defined(DEBUG) || defined(_DEBUG)
  440. m_dwOwningThread = 0;
  441. #endif
  442. if (fTakeLock)
  443. this->Lock();
  444. }
  445. ~CAutoUnlockMutex(void)
  446. {
  447. _ASSERT(m_cLocks <= 1);
  448. if (m_hmut != NULL)
  449. {
  450. #if defined(DEBUG) || defined(_DEBUG)
  451. if (m_cLocks > 0)
  452. _ASSERT(m_dwOwningThread == GetCurrentThreadId());
  453. #endif
  454. while(m_cLocks > 0)
  455. {
  456. ReleaseMutex(m_hmut);
  457. m_cLocks--;
  458. }
  459. }
  460. }
  461. BOOL Lock(DWORD dwTimeout = INFINITE)
  462. {
  463. if (m_hmut != NULL)
  464. {
  465. if (WaitForSingleObject(m_hmut, dwTimeout) != WAIT_OBJECT_0)
  466. return FALSE;
  467. m_cLocks++;
  468. #if defined(DEBUG) || defined(_DEBUG)
  469. m_dwOwningThread = GetCurrentThreadId();
  470. #endif
  471. }
  472. return TRUE;
  473. }
  474. void Unlock(void)
  475. {
  476. _ASSERT(m_cLocks > 0);
  477. _ASSERT(m_dwOwningThread == GetCurrentThreadId());
  478. if (m_hmut != NULL && m_cLocks > 0)
  479. {
  480. m_cLocks--;
  481. ReleaseMutex(m_hmut);
  482. }
  483. }
  484. };
  485. #endif