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.

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