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.

1023 lines
25 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: OSInd.cpp
  6. * Content: OS indirection functions to abstract OS specific items.
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/12/99 jtk Created
  12. * 09/21/99 rodtoll Fixed for retail builds
  13. * 09/22/99 jtk Added callstacks to memory allocations
  14. * 08/28/2000 masonb Voice Merge: Allow new and delete with size of 0
  15. * 11/28/2000 rodtoll WinBug #206257 - Retail DPNET.DLL links to DebugBreak()
  16. * 12/22/2000 aarono ManBug # 190380 use process heap for retail
  17. * 10/16/2001 vanceo Add AssertNoCriticalSectionsTakenByThisThread capability
  18. ***************************************************************************/
  19. #include "dncmni.h"
  20. #define PROF_SECT _T("DirectPlay8")
  21. //**********************************************************************
  22. // Constant definitions
  23. //**********************************************************************
  24. //**********************************************************************
  25. // Macro definitions
  26. //**********************************************************************
  27. //**********************************************************************
  28. // Structure definitions
  29. //**********************************************************************
  30. //**********************************************************************
  31. // Variable definitions
  32. //**********************************************************************
  33. //
  34. // debug variable to make sure we're initialized before having any functions
  35. // called
  36. //
  37. DEBUG_ONLY( static BOOL g_fOSIndirectionLayerInitialized = FALSE );
  38. //
  39. // OS items
  40. //
  41. #if ((! defined(WINCE)) && (! defined(_XBOX)))
  42. static OSVERSIONINFO g_OSVersionInfo;
  43. #endif // ! WINCE and ! _XBOX
  44. #ifndef DPNBUILD_NOSERIALSP
  45. static HINSTANCE g_hApplicationInstance;
  46. #endif // ! DPNBUILD_NOSERIALSP
  47. //
  48. // Global Pools
  49. //
  50. #if ((! defined(DPNBUILD_LIBINTERFACE)) && (! defined(DPNBUILD_NOCLASSFACTORY)))
  51. CFixedPool g_fpClassFactories;
  52. CFixedPool g_fpObjectDatas;
  53. CFixedPool g_fpInterfaceLists;
  54. #endif // ! DPNBUILD_LIBINTERFACE and ! DPNBUILD_NOCLASSFACTORY
  55. #ifdef WINNT
  56. PSECURITY_ATTRIBUTES g_psa = NULL;
  57. SECURITY_ATTRIBUTES g_sa;
  58. BYTE g_pSD[SECURITY_DESCRIPTOR_MIN_LENGTH];
  59. BOOL g_fDaclInited = FALSE;
  60. PACL g_pEveryoneACL = NULL;
  61. #endif // WINNT
  62. #ifndef DPNBUILD_LIBINTERFACE
  63. #define CLASSFAC_POOL_INITED 0x00000001
  64. #define OBJDATA_POOL_INITED 0x00000002
  65. #define INTLIST_POOL_INITED 0x00000004
  66. #endif // ! DPNBUILD_LIBINTERFACE
  67. #ifdef DBG
  68. #define HANDLE_TRACKING_INITED 0x00000008
  69. #endif // DBG
  70. #if ((defined(DBG)) || (defined(DPNBUILD_FIXEDMEMORYMODEL)))
  71. #define MEMORY_TRACKING_INITED 0x00000010
  72. #endif // DBG or DPNBUILD_FIXEDMEMORYMODEL
  73. #if ((defined(DBG)) && (! defined(DPNBUILD_ONLYONETHREAD)))
  74. #define CRITSEC_TRACKING_INITED 0x00000020
  75. #endif // DBG and ! DPNBUILD_ONLYONETHREAD
  76. #if !defined(DPNBUILD_LIBINTERFACE) || defined(DBG) || defined(DPNBUILD_FIXEDMEMORYMODEL)
  77. DWORD g_dwCommonInitFlags = 0;
  78. #endif // !defined(DPNBUILD_LIBINTERFACE) || defined(DBG) || defined(DPNBUILD_FIXEDMEMORYMODEL)
  79. //**********************************************************************
  80. // Function prototypes
  81. //**********************************************************************
  82. //**********************************************************************
  83. // Function definitions
  84. //**********************************************************************
  85. //**********************************************************************
  86. // ------------------------------
  87. // DNOSIndirectionInit - initialize the OS indirection layer
  88. //
  89. // Entry: Nothing
  90. //
  91. // Exit: Boolean indicating success
  92. // TRUE = initialization successful
  93. // FALSE = initialization unsuccessful
  94. // ------------------------------
  95. #undef DPF_MODNAME
  96. #define DPF_MODNAME "DNOSIndirectionInit"
  97. BOOL DNOSIndirectionInit( DWORD_PTR dwpMaxMemUsage )
  98. {
  99. BOOL fReturn;
  100. #ifdef DBG
  101. DNASSERT( g_fOSIndirectionLayerInitialized == FALSE );
  102. #endif // DBG
  103. //
  104. // initialize
  105. //
  106. fReturn = TRUE;
  107. #if ((! defined(WINCE)) && (! defined(_XBOX)))
  108. //
  109. // note OS version
  110. //
  111. memset( &g_OSVersionInfo, 0x00, sizeof( g_OSVersionInfo ) );
  112. g_OSVersionInfo.dwOSVersionInfoSize = sizeof( g_OSVersionInfo );
  113. if ( GetVersionEx( &g_OSVersionInfo ) == FALSE )
  114. {
  115. goto Failure;
  116. }
  117. #endif // ! WINCE and ! _XBOX
  118. #ifndef DPNBUILD_NOSERIALSP
  119. //
  120. // note application instance
  121. //
  122. g_hApplicationInstance = GetModuleHandle( NULL );
  123. if ( g_hApplicationInstance == NULL )
  124. {
  125. DWORD dwError;
  126. dwError = GetLastError();
  127. DPFX(DPFPREP, 0, "Failed to GetModuleHandle: 0x%x", dwError );
  128. goto Failure;
  129. }
  130. #endif // ! DPNBUILD_NOSERIALSP
  131. #if ((defined(DBG)) && (! defined(DPNBUILD_ONLYONETHREAD)))
  132. //
  133. // initialize critical section tracking code before anything else!
  134. //
  135. if ( DNCSTrackInitialize() == FALSE )
  136. {
  137. DPFX(DPFPREP, 0, "Failed to initialize critsec tracking code!" );
  138. DNASSERT( FALSE );
  139. goto Failure;
  140. }
  141. g_dwCommonInitFlags |= CRITSEC_TRACKING_INITED;
  142. #endif // DBG and ! DPNBUILD_ONLYONETHREAD
  143. #if ((defined(DBG)) || (defined(DPNBUILD_FIXEDMEMORYMODEL)))
  144. //
  145. // initialize memory tracking before creating new memory heap
  146. //
  147. if ( DNMemoryTrackInitialize(dwpMaxMemUsage) == FALSE )
  148. {
  149. DPFX(DPFPREP, 0, "Failed to initialize memory tracking code!" );
  150. DNASSERT( FALSE );
  151. goto Failure;
  152. }
  153. g_dwCommonInitFlags |= MEMORY_TRACKING_INITED;
  154. #endif // DBG or DPNBUILD_FIXEDMEMORYMODEL
  155. #ifdef DBG
  156. //
  157. // initialize handle tracking
  158. //
  159. if ( DNHandleTrackInitialize() == FALSE )
  160. {
  161. DPFX(DPFPREP, 0, "Failed to initialize handle tracking code!" );
  162. DNASSERT( FALSE );
  163. goto Failure;
  164. }
  165. g_dwCommonInitFlags |= HANDLE_TRACKING_INITED;
  166. #endif // DBG
  167. #if ((! defined(DPNBUILD_LIBINTERFACE)) && (! defined(DPNBUILD_NOCLASSFACTORY)))
  168. //
  169. // Initialize global pools
  170. //
  171. if (!g_fpClassFactories.Initialize( sizeof( _IDirectPlayClassFactory ), NULL, NULL, NULL, NULL))
  172. {
  173. DPFX(DPFPREP, 0, "Failed to initialize class factory pool!" );
  174. goto Failure;
  175. }
  176. g_dwCommonInitFlags |= CLASSFAC_POOL_INITED;
  177. if (!g_fpObjectDatas.Initialize( sizeof( _OBJECT_DATA ), NULL, NULL, NULL, NULL))
  178. {
  179. DPFX(DPFPREP, 0, "Failed to initialize object data pool!" );
  180. goto Failure;
  181. }
  182. g_dwCommonInitFlags |= OBJDATA_POOL_INITED;
  183. if (!g_fpInterfaceLists.Initialize( sizeof( _INTERFACE_LIST ), NULL, NULL, NULL, NULL))
  184. {
  185. DPFX(DPFPREP, 0, "Failed to initialize interface list pool!" );
  186. goto Failure;
  187. }
  188. g_dwCommonInitFlags |= INTLIST_POOL_INITED;
  189. #endif // ! DPNBUILD_LIBINTERFACE and ! DPNBUILD_NOCLASSFACTORY
  190. srand(GETTIMESTAMP());
  191. #if (((! defined(WINCE)) && (! defined(_XBOX))) || (! defined(DPNBUILD_NOSERIALSP)) || (defined(DBG)) || (defined(DPNBUILD_FIXEDMEMORYMODEL)) || ((! defined(DPNBUILD_LIBINTERFACE)) && (! defined(DPNBUILD_NOCLASSFACTORY))) )
  192. Exit:
  193. #endif // (! WINCE and ! _XBOX) or ! DPNBUILD_NOSERIALSP or DBG or DPNBUILD_FIXEDMEMORYMODEL or (! DPNBUILD_LIBINTERFACE and ! DPNBUILD_NOCLASSFACTORY)
  194. if ( fReturn != FALSE )
  195. {
  196. DEBUG_ONLY( g_fOSIndirectionLayerInitialized = TRUE );
  197. }
  198. return fReturn;
  199. #if (((! defined(WINCE)) && (! defined(_XBOX))) || (! defined(DPNBUILD_NOSERIALSP)) || (defined(DBG)) || (defined(DPNBUILD_FIXEDMEMORYMODEL)) || ((! defined(DPNBUILD_LIBINTERFACE)) && (! defined(DPNBUILD_NOCLASSFACTORY))) )
  200. Failure:
  201. fReturn = FALSE;
  202. DNOSIndirectionDeinit();
  203. goto Exit;
  204. #endif // (! WINCE and ! _XBOX) or ! DPNBUILD_NOSERIALSP or DBG or DPNBUILD_FIXEDMEMORYMODEL or (! DPNBUILD_LIBINTERFACE and ! DPNBUILD_NOCLASSFACTORY)
  205. }
  206. //**********************************************************************
  207. //**********************************************************************
  208. // ------------------------------
  209. // DNOSIndirectionDeinit - deinitialize OS indirection layer
  210. //
  211. // Entry: Nothing
  212. //
  213. // Exit: Nothing
  214. // ------------------------------
  215. #undef DPF_MODNAME
  216. #define DPF_MODNAME "DNOSIndirectionDeinit"
  217. void DNOSIndirectionDeinit( void )
  218. {
  219. #if ((! defined(DPNBUILD_LIBINTERFACE)) && (! defined(DPNBUILD_NOCLASSFACTORY)))
  220. //
  221. // DeInitialize global pools
  222. //
  223. if (g_dwCommonInitFlags & CLASSFAC_POOL_INITED)
  224. {
  225. g_fpClassFactories.DeInitialize();
  226. }
  227. if (g_dwCommonInitFlags & OBJDATA_POOL_INITED)
  228. {
  229. g_fpObjectDatas.DeInitialize();
  230. }
  231. if (g_dwCommonInitFlags & INTLIST_POOL_INITED)
  232. {
  233. g_fpInterfaceLists.DeInitialize();
  234. }
  235. #endif // ! DPNBUILD_LIBINTERFACE and ! DPNBUILD_NOCLASSFACTORY
  236. #ifdef DBG
  237. if (g_dwCommonInitFlags & HANDLE_TRACKING_INITED)
  238. {
  239. if (DNHandleTrackDumpLeaks())
  240. {
  241. // There were leaks, break so we can look at the log
  242. DNASSERT(0);
  243. }
  244. DNHandleTrackDeinitialize();
  245. }
  246. #endif // DBG
  247. #if ((defined(DBG)) && (! defined(DPNBUILD_ONLYONETHREAD)))
  248. //
  249. // Display CritSec leaks before displaying memory leaks, because displaying memory leaks
  250. // may free the memory for the CritSec and corrupt the CritSec bilink
  251. //
  252. if (g_dwCommonInitFlags & CRITSEC_TRACKING_INITED)
  253. {
  254. if (DNCSTrackDumpLeaks())
  255. {
  256. // There were leaks, break so we can look at the log
  257. DNASSERT(0);
  258. }
  259. DNCSTrackDeinitialize();
  260. }
  261. #endif // DBG and ! DPNBUILD_ONLYONETHREAD
  262. #if ((defined(DBG)) || (defined(DPNBUILD_FIXEDMEMORYMODEL)))
  263. if (g_dwCommonInitFlags & MEMORY_TRACKING_INITED)
  264. {
  265. #ifdef DBG
  266. if (DNMemoryTrackDumpLeaks())
  267. {
  268. // There were leaks, break so we can look at the log
  269. DNASSERT(0);
  270. }
  271. #endif // DBG
  272. DNMemoryTrackDeinitialize();
  273. }
  274. #endif // DBG or DPNBUILD_FIXEDMEMORYMODEL
  275. #ifdef WINNT
  276. // This should be done after functions that use a Dacl will no longer be
  277. // called (CreateMutex, CreateFile, etc).
  278. if (g_pEveryoneACL)
  279. {
  280. HeapFree(GetProcessHeap(), 0, g_pEveryoneACL);
  281. g_pEveryoneACL = NULL;
  282. }
  283. #endif // WINNT
  284. DEBUG_ONLY( g_fOSIndirectionLayerInitialized = FALSE );
  285. #if !defined(DPNBUILD_LIBINTERFACE) || defined(DBG)
  286. g_dwCommonInitFlags = 0;
  287. #endif // !defined(DPNBUILD_LIBINTERFACE) || defined(DBG)
  288. }
  289. //**********************************************************************
  290. #undef DPF_MODNAME
  291. #define DPF_MODNAME "DNinet_ntow"
  292. void DNinet_ntow( IN_ADDR in, WCHAR* pwsz )
  293. {
  294. // NOTE: pwsz should be 16 characters (4 3-digit numbers + 3 '.' + \0)
  295. swprintf(pwsz, L"%d.%d.%d.%d", in.s_net, in.s_host, in.s_lh, in.s_impno);
  296. }
  297. #undef DPF_MODNAME
  298. #define DPF_MODNAME "DNGetRandomNumber"
  299. DWORD DNGetRandomNumber()
  300. {
  301. return (rand() | (rand() << 16));
  302. }
  303. #if ((! defined(WINCE)) && (! defined(_XBOX)))
  304. //**********************************************************************
  305. // ------------------------------
  306. // DNGetOSType - get OS type
  307. //
  308. // Entry: Nothing
  309. //
  310. // Exit: OS type
  311. // ------------------------------
  312. #undef DPF_MODNAME
  313. #define DPF_MODNAME "DNGetOSType"
  314. UINT_PTR DNGetOSType( void )
  315. {
  316. #ifdef DBG
  317. DNASSERT( g_fOSIndirectionLayerInitialized != FALSE );
  318. #endif // DBG
  319. return g_OSVersionInfo.dwPlatformId;
  320. }
  321. #endif // ! WINCE and ! _XBOX
  322. #ifdef WINNT
  323. //**********************************************************************
  324. // ------------------------------
  325. // DNOSIsXPOrGreater - return TRUE if OS is WindowsXP or later or NT flavor
  326. //
  327. // Entry: Nothing
  328. //
  329. // Exit: BOOL
  330. // ------------------------------
  331. #undef DPF_MODNAME
  332. #define DPF_MODNAME "DNOSIsXPOrGreater"
  333. BOOL DNOSIsXPOrGreater( void )
  334. {
  335. #ifdef DBG
  336. DNASSERT( g_fOSIndirectionLayerInitialized != FALSE );
  337. #endif // DBG
  338. return ((g_OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
  339. ((g_OSVersionInfo.dwMajorVersion > 5) || ((g_OSVersionInfo.dwMajorVersion == 5) && (g_OSVersionInfo.dwMinorVersion >= 1)))
  340. );
  341. }
  342. //**********************************************************************
  343. //**********************************************************************
  344. // ------------------------------
  345. // DNGetNullDacl - get a SECURITY_ATTRIBUTE structure that specifies a
  346. // NULL DACL which is accesible by all users.
  347. //
  348. // Entry: Nothing
  349. //
  350. // Exit: PSECURITY_ATTRIBUTES
  351. // ------------------------------
  352. #undef DPF_MODNAME
  353. #define DPF_MODNAME "DNGetNullDacl"
  354. PSECURITY_ATTRIBUTES DNGetNullDacl()
  355. {
  356. PSID psidEveryone = NULL;
  357. SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
  358. DWORD dwAclSize;
  359. // This is done to make this function independent of DNOSIndirectionInit so that the debug
  360. // layer can call it before the indirection layer is initialized.
  361. if (!g_fDaclInited)
  362. {
  363. if (!InitializeSecurityDescriptor((SECURITY_DESCRIPTOR*)g_pSD, SECURITY_DESCRIPTOR_REVISION))
  364. {
  365. DPFX(DPFPREP, 0, "Failed to initialize security descriptor" );
  366. goto Error;
  367. }
  368. // Create SID for the Everyone group.
  369. if (!AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0,
  370. 0, 0, 0, 0, 0, 0, &psidEveryone))
  371. {
  372. DPFX(DPFPREP, 0, "Failed to allocate Everyone SID" );
  373. goto Error;
  374. }
  375. dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidEveryone) - sizeof(DWORD);
  376. // Allocate the ACL, this won't be a tracked allocation and we will let process cleanup destroy it
  377. g_pEveryoneACL = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
  378. if (g_pEveryoneACL == NULL)
  379. {
  380. DPFX(DPFPREP, 0, "Failed to allocate ACL buffer" );
  381. goto Error;
  382. }
  383. // Intialize the ACL.
  384. if (!InitializeAcl(g_pEveryoneACL, dwAclSize, ACL_REVISION))
  385. {
  386. DPFX(DPFPREP, 0, "Failed to initialize ACL" );
  387. goto Error;
  388. }
  389. // Add the ACE.
  390. if (!AddAccessAllowedAce(g_pEveryoneACL, ACL_REVISION, GENERIC_ALL, psidEveryone))
  391. {
  392. DPFX(DPFPREP, 0, "Failed to add ACE to ACL" );
  393. goto Error;
  394. }
  395. // We no longer need the SID that was allocated.
  396. FreeSid(psidEveryone);
  397. psidEveryone = NULL;
  398. // Add the ACL to the security descriptor..
  399. if (!SetSecurityDescriptorDacl((SECURITY_DESCRIPTOR*)g_pSD, TRUE, g_pEveryoneACL, FALSE))
  400. {
  401. DPFX(DPFPREP, 0, "Failed to add ACL to security descriptor" );
  402. goto Error;
  403. }
  404. g_sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  405. g_sa.lpSecurityDescriptor = g_pSD;
  406. g_sa.bInheritHandle = FALSE;
  407. g_psa = &g_sa;
  408. g_fDaclInited = TRUE;
  409. }
  410. Error:
  411. if (psidEveryone)
  412. {
  413. FreeSid(psidEveryone);
  414. psidEveryone = NULL;
  415. }
  416. return g_psa;
  417. }
  418. //**********************************************************************
  419. #endif // WINNT
  420. #ifndef DPNBUILD_NOSERIALSP
  421. //**********************************************************************
  422. // ------------------------------
  423. // DNGetApplicationInstance - application instance
  424. //
  425. // Entry: Nothing
  426. //
  427. // Exit: Application instance
  428. // ------------------------------
  429. #undef DPF_MODNAME
  430. #define DPF_MODNAME "DNGetApplicationInstance"
  431. HINSTANCE DNGetApplicationInstance( void )
  432. {
  433. #ifdef DBG
  434. DNASSERT( g_fOSIndirectionLayerInitialized != FALSE );
  435. #endif // DBG
  436. return g_hApplicationInstance;
  437. }
  438. //**********************************************************************
  439. #endif // ! DPNBUILD_NOSERIALSP
  440. #ifndef DPNBUILD_ONLYONETHREAD
  441. //**********************************************************************
  442. // ------------------------------
  443. // DNOSInitializeCriticalSection - initialize a critical section
  444. //
  445. // Entry: Pointer to critical section
  446. //
  447. // Exit: Boolean indicating success
  448. // TRUE = success
  449. // FALSE = failue
  450. // ------------------------------
  451. #undef DPF_MODNAME
  452. #define DPF_MODNAME "DNOSInitializeCriticalSection"
  453. BOOL DNOSInitializeCriticalSection( CRITICAL_SECTION* pCriticalSection )
  454. {
  455. BOOL fReturn;
  456. DNASSERT( pCriticalSection != NULL );
  457. fReturn = TRUE;
  458. //
  459. // attempt to enter the critical section once
  460. //
  461. _try
  462. {
  463. #ifdef WINNT
  464. // Pre-allocate the critsec event by setting the high bit of the spin count and set spin to 1000
  465. // NT converts the spin to 0 for single proc machines.
  466. fReturn = InitializeCriticalSectionAndSpinCount( pCriticalSection , 0x80000000 | 1000);
  467. #else
  468. InitializeCriticalSection( pCriticalSection );
  469. #endif // WINNT
  470. }
  471. _except( EXCEPTION_EXECUTE_HANDLER )
  472. {
  473. fReturn = FALSE;
  474. }
  475. _try
  476. {
  477. if (fReturn)
  478. {
  479. EnterCriticalSection( pCriticalSection );
  480. }
  481. }
  482. _except( EXCEPTION_EXECUTE_HANDLER )
  483. {
  484. DeleteCriticalSection(pCriticalSection);
  485. fReturn = FALSE;
  486. }
  487. //
  488. // if we didn't fail on entering the critical section, make sure
  489. // we release it
  490. //
  491. if ( fReturn != FALSE )
  492. {
  493. LeaveCriticalSection( pCriticalSection );
  494. }
  495. return fReturn;
  496. }
  497. //**********************************************************************
  498. #endif // !DPNBUILD_ONLYONETHREAD
  499. #ifdef DBG
  500. #ifdef WINCE
  501. #undef DPF_MODNAME
  502. #define DPF_MODNAME "DNGetProfileInt"
  503. UINT DNGetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault)
  504. {
  505. DWORD dwResult;
  506. CRegistry reg;
  507. DNASSERT(_tcscmp(lpszSection, _T("DirectPlay8")) == 0);
  508. if (!reg.Open(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\DirectPlay8")))
  509. {
  510. // NOTE: This will occur during DllRegisterServer for the first time
  511. return nDefault;
  512. }
  513. if (!reg.ReadDWORD(lpszEntry, &dwResult))
  514. {
  515. return nDefault;
  516. }
  517. return dwResult;
  518. }
  519. #else // ! WINCE
  520. #if ((defined(_XBOX)) && (! defined(XBOX_ON_DESKTOP)))
  521. #undef DPF_MODNAME
  522. #define DPF_MODNAME "DNGetProfileInt"
  523. UINT DNGetProfileInt(LPCTSTR lpszSection, LPCTSTR lpszEntry, int nDefault)
  524. {
  525. DWORD dwResult;
  526. FILE * pFile = NULL;
  527. TCHAR tszLine[256];
  528. TCHAR * ptszTrimStart;
  529. TCHAR * ptszTrimEnd;
  530. BOOL fInSection = FALSE;
  531. DNASSERT(_tcscmp(lpszSection, _T("DirectPlay8")) == 0);
  532. //
  533. // Populate the default return value.
  534. //
  535. dwResult = nDefault;
  536. //
  537. // Open a "win.ini" file in the root of the title's launch directory.
  538. //
  539. pFile = fopen(_T("D:\\win.ini"), "r");
  540. if (pFile == NULL)
  541. {
  542. goto Exit;
  543. }
  544. //
  545. // Look for the section and entry.
  546. //
  547. while (_fgetts(tszLine, (sizeof(tszLine) - sizeof(TCHAR)), pFile) != NULL)
  548. {
  549. //
  550. // Trim whitespace from the beginning of the line.
  551. //
  552. ptszTrimStart = tszLine;
  553. while (((*ptszTrimStart) == _T('\n')) ||
  554. ((*ptszTrimStart) == _T('\r')) ||
  555. ((*ptszTrimStart) == _T(' ')) ||
  556. ((*ptszTrimStart) == _T('\t')))
  557. {
  558. if ((*ptszTrimStart) == 0)
  559. {
  560. break;
  561. }
  562. ptszTrimStart++;
  563. }
  564. //
  565. // Trim whitespace off the end of the line.
  566. //
  567. ptszTrimEnd = ptszTrimStart + _tcslen(ptszTrimStart) - 1;
  568. while (((*ptszTrimEnd) == _T('\n')) ||
  569. ((*ptszTrimEnd) == _T('\r')) ||
  570. ((*ptszTrimEnd) == _T(' ')) ||
  571. ((*ptszTrimEnd) == _T('\t')))
  572. {
  573. if (ptszTrimEnd <= ptszTrimStart)
  574. {
  575. break;
  576. }
  577. ptszTrimEnd--;
  578. }
  579. //
  580. // Ignore commented lines (starts with semicolon).
  581. //
  582. if ((*ptszTrimStart) != _T(';'))
  583. {
  584. //
  585. // If it starts and ends with brackets, it's a section header.
  586. //
  587. if (((*ptszTrimStart) == _T('[')) && ((*ptszTrimEnd) == _T(']')))
  588. {
  589. //
  590. // If we were in the section, then we've left it and we're
  591. // done.
  592. //
  593. if (fInSection)
  594. {
  595. break;
  596. }
  597. //
  598. // Trim whitespace from inside the start of the brackets.
  599. //
  600. *ptszTrimEnd = 0;
  601. ptszTrimEnd--;
  602. ptszTrimStart++;
  603. while (((*ptszTrimStart) == _T('\n')) ||
  604. ((*ptszTrimStart) == _T('\r')) ||
  605. ((*ptszTrimStart) == _T(' ')) ||
  606. ((*ptszTrimStart) == _T('\t')))
  607. {
  608. if ((*ptszTrimStart) == 0)
  609. {
  610. break;
  611. }
  612. ptszTrimStart++;
  613. }
  614. while (((*ptszTrimEnd) == _T('\n')) ||
  615. ((*ptszTrimEnd) == _T('\r')) ||
  616. ((*ptszTrimEnd) == _T(' ')) ||
  617. ((*ptszTrimEnd) == _T('\t')))
  618. {
  619. if (ptszTrimEnd <= ptszTrimStart)
  620. {
  621. break;
  622. }
  623. ptszTrimEnd--;
  624. }
  625. *(ptszTrimEnd + 1) = 0;
  626. //
  627. // Is this the right section?
  628. //
  629. if (_tcsicmp(ptszTrimStart, lpszSection) == 0)
  630. {
  631. fInSection = TRUE;
  632. }
  633. }
  634. else
  635. {
  636. //
  637. // If we're in the section, determine the key
  638. // name.
  639. //
  640. if (fInSection)
  641. {
  642. TCHAR * ptszKeyEnd;
  643. TCHAR * ptszValue;
  644. *(ptszTrimEnd + 1) = 0;
  645. ptszKeyEnd = ptszTrimStart;
  646. while ((ptszKeyEnd < ptszTrimEnd) &&
  647. ((*ptszKeyEnd) != _T('=')))
  648. {
  649. ptszKeyEnd++;
  650. }
  651. if ((*ptszKeyEnd) == _T('='))
  652. {
  653. ptszValue = ptszKeyEnd + 1;
  654. ptszKeyEnd--;
  655. while (((*ptszKeyEnd) == _T('\n')) ||
  656. ((*ptszKeyEnd) == _T('\r')) ||
  657. ((*ptszKeyEnd) == _T(' ')) ||
  658. ((*ptszKeyEnd) == _T('\t')))
  659. {
  660. if (ptszKeyEnd <= ptszTrimStart)
  661. {
  662. break;
  663. }
  664. ptszKeyEnd--;
  665. }
  666. *(ptszKeyEnd + 1) = 0;
  667. //
  668. // If we matched the key name, convert the
  669. // value and bail.
  670. //
  671. if (_tcsicmp(ptszTrimStart, lpszEntry) == 0)
  672. {
  673. dwResult = _ttoi(ptszValue);
  674. goto Exit;
  675. }
  676. }
  677. }
  678. else
  679. {
  680. //
  681. // Not in section.
  682. //
  683. }
  684. }
  685. }
  686. else
  687. {
  688. //
  689. // Line is commented, ignore.
  690. //
  691. }
  692. }
  693. Exit:
  694. if (pFile != NULL)
  695. {
  696. fclose(pFile);
  697. pFile = NULL;
  698. }
  699. return dwResult;
  700. }
  701. #endif // _XBOX and ! XBOX_ON_DESKTOP
  702. #endif // ! WINCE
  703. #endif // DBG
  704. #if defined(WINCE) && !defined(WINCE_ON_DESKTOP)
  705. //**********************************************************************
  706. //**
  707. //** Begin CE layer. Here we implement functions we need that aren't on CE.
  708. //**
  709. //**********************************************************************
  710. #undef DPF_MODNAME
  711. #define DPF_MODNAME "OpenEvent"
  712. HANDLE WINAPI OpenEvent(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
  713. {
  714. HANDLE h;
  715. h = CreateEvent(0, 1, 0, lpName);
  716. if (!h)
  717. {
  718. return NULL;
  719. }
  720. if (GetLastError() != ERROR_ALREADY_EXISTS)
  721. {
  722. CloseHandle(h);
  723. return NULL;
  724. }
  725. return h;
  726. }
  727. #undef DPF_MODNAME
  728. #define DPF_MODNAME "OpenFileMapping"
  729. HANDLE WINAPI OpenFileMapping(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
  730. {
  731. HANDLE h;
  732. DWORD dwFlags = 0;
  733. if (dwDesiredAccess & FILE_MAP_WRITE)
  734. {
  735. // If they ask for FILE_MAP_ALL_ACCESS or FILE_MAP_WRITE, they get read and write
  736. dwFlags = PAGE_READWRITE;
  737. }
  738. else
  739. {
  740. // If they only ask for FILE_MAP_READ, they get read only
  741. dwFlags = PAGE_READONLY;
  742. }
  743. h = CreateFileMapping(INVALID_HANDLE_VALUE, 0, dwFlags, 0, 1, lpName);
  744. if (!h)
  745. {
  746. return NULL;
  747. }
  748. if (GetLastError() != ERROR_ALREADY_EXISTS)
  749. {
  750. CloseHandle(h);
  751. return NULL;
  752. }
  753. return h;
  754. }
  755. #undef DPF_MODNAME
  756. #define DPF_MODNAME "OpenMutex"
  757. HANDLE WINAPI OpenMutex(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName)
  758. {
  759. HANDLE h;
  760. h = CreateMutex(0, 0, lpName);
  761. if (!h)
  762. {
  763. return NULL;
  764. }
  765. if (GetLastError() != ERROR_ALREADY_EXISTS)
  766. {
  767. CloseHandle(h);
  768. return NULL;
  769. }
  770. return h;
  771. }
  772. /*
  773. #ifdef _X86_
  774. __declspec(naked)
  775. LONG WINAPI InterlockedExchangeAdd( LPLONG Addend, LONG Increment )
  776. {
  777. __asm
  778. {
  779. mov ecx, [esp + 4] ; get addend address
  780. mov eax, [esp + 8] ; get increment value
  781. lock xadd [ecx], eax ; exchange add}
  782. ret
  783. }
  784. }
  785. #endif // _X86
  786. */
  787. #endif // WINCE
  788. //**********************************************************************
  789. //**
  790. //** End CE layer. Here we implement functions we need that aren't on CE.
  791. //**
  792. //**********************************************************************
  793. #if ((defined(WINCE)) || (defined(DPNBUILD_LIBINTERFACE)))
  794. #undef DPF_MODNAME
  795. #define DPF_MODNAME "DNCoCreateGuid"
  796. HRESULT DNCoCreateGuid(GUID* pguid)
  797. {
  798. pguid->Data1 = (rand() << 16) | rand();
  799. pguid->Data2 = (WORD)rand();
  800. pguid->Data3 = (WORD)rand();
  801. pguid->Data4[0] = (BYTE)rand();
  802. pguid->Data4[1] = (BYTE)rand();
  803. pguid->Data4[2] = (BYTE)rand();
  804. pguid->Data4[3] = (BYTE)rand();
  805. pguid->Data4[4] = (BYTE)rand();
  806. pguid->Data4[5] = (BYTE)rand();
  807. pguid->Data4[6] = (BYTE)rand();
  808. pguid->Data4[7] = (BYTE)rand();
  809. return S_OK;
  810. }
  811. #endif // WINCE or DPNBUILD_LIBINTERFACE
  812. #ifndef DPNBUILD_NOPARAMVAL
  813. BOOL IsValidStringA( const CHAR * const lpsz )
  814. {
  815. #ifndef WINCE
  816. return (!IsBadStringPtrA( lpsz, 0xFFFF ) );
  817. #else
  818. const char* szTmpLoc = lpsz;
  819. //
  820. // If it is a NULL pointer just return FALSE, they are always bad
  821. //
  822. if (szTmpLoc == NULL)
  823. {
  824. return FALSE;
  825. }
  826. _try
  827. {
  828. for( ; *szTmpLoc ; szTmpLoc++ );
  829. }
  830. _except(EXCEPTION_EXECUTE_HANDLER)
  831. {
  832. return FALSE;
  833. }
  834. return TRUE;
  835. #endif // WINCE
  836. }
  837. BOOL IsValidStringW( const WCHAR * const lpwsz )
  838. {
  839. #ifdef WINNT
  840. //
  841. // This function is only valid on NT.
  842. // It exists for WIN9x, but only via the MS Layer for Unicode which requires us to jump through hoops when linking
  843. //
  844. return (!IsBadStringPtrW( lpwsz, 0xFFFF ) );
  845. #else
  846. const wchar_t *szTmpLoc = lpwsz;
  847. //
  848. // If it is a NULL pointer just return FALSE, they are always bad
  849. //
  850. if( szTmpLoc == NULL )
  851. {
  852. return FALSE;
  853. }
  854. _try
  855. {
  856. for( ; *szTmpLoc ; szTmpLoc++ );
  857. }
  858. _except( EXCEPTION_EXECUTE_HANDLER )
  859. {
  860. return FALSE;
  861. }
  862. return TRUE;
  863. #endif // WINNT
  864. }
  865. #endif // !DPNBUILD_NOPARAMVAL