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.

1584 lines
34 KiB

  1. #include "config.h"
  2. #define HANDLE WINHANDLE
  3. #include <windows.h>
  4. #undef HANDLE
  5. #include <dos.h>
  6. #include <malloc.h>
  7. #include <string.h>
  8. #include <time.h>
  9. #include <ctype.h>
  10. #include <io.h>
  11. #include <stdarg.h>
  12. #include <stdlib.h>
  13. /* this build is for DAYTONA
  14. /**/
  15. #define DAYTONA 1
  16. /* make sure the definition between os.h/_jet.h is the same as in windows.h */
  17. #undef FAR
  18. #undef NEAR
  19. #undef PASCAL
  20. #undef far
  21. #undef near
  22. #undef cdecl
  23. #undef pascal
  24. #undef MAKELONG
  25. #undef HIWORD
  26. #include "daedef.h"
  27. #include "util.h"
  28. #include "b71iseng.h"
  29. DeclAssertFile; /* Declare file name for assert macros */
  30. VOID SysGetDriveGeometry( HANDLE handle );
  31. DWORD DwSYSGetLastError( VOID )
  32. {
  33. DWORD dw = GetLastError();
  34. return dw;
  35. }
  36. LOCAL ERR ErrCheckError( VOID );
  37. LOCAL ERR ErrSYSIGetLastError( ERR errDefault )
  38. {
  39. ERR err = errDefault;
  40. DWORD dw = GetLastError();
  41. /* maps system error to JET error, or sets err to given
  42. /* default error.
  43. /**/
  44. switch ( dw )
  45. {
  46. case ERROR_TOO_MANY_OPEN_FILES:
  47. err = JET_errNoMoreFiles;
  48. break;
  49. default:
  50. break;
  51. }
  52. return err;
  53. }
  54. ERR ErrSysCheckLangid( LANGID langid )
  55. {
  56. ERR err;
  57. WCHAR rgwA[1];
  58. WCHAR rgwB[1];
  59. //NOTE: Julie Bennett said that starting with DAYTONA, the best call to use
  60. // is IsValidLocale(). I don't have libraries to link to for that yet.
  61. // She said that the best thing (for performance reasons) to do in NT
  62. // (pre-daytona) is call CompareStringW with counts of -1. This will
  63. // determine if the langid is currently configured on the machine.
  64. // (not just a valid langid somewhere in the universe).
  65. rgwA[0] = 0;
  66. rgwB[0] = 0;
  67. if ( CompareStringW( MAKELCID( langid, 0 ), NORM_IGNORECASE, rgwA, -1, rgwB, -1 ) == 0 )
  68. {
  69. Assert( GetLastError() == ERROR_INVALID_PARAMETER );
  70. err = JET_errInvalidLanguageId;
  71. }
  72. else
  73. {
  74. err = JET_errSuccess;
  75. }
  76. return err;
  77. }
  78. ERR ErrSysMapString(
  79. LANGID langid,
  80. BYTE *pbColumn,
  81. INT cbColumn,
  82. BYTE *rgbSeg,
  83. INT cbMax,
  84. INT *pcbSeg )
  85. {
  86. ERR err = JET_errSuccess;
  87. // UNDONE: refine this constant based on unicode key format
  88. /* 3 * number of unicode character bytes + 7 overhead bytes + 10 fudge
  89. /**/
  90. #define JET_cbUnicodeKeyMost ( 3 * JET_cbColumnMost + 7 + 10 )
  91. BYTE rgbKey[JET_cbUnicodeKeyMost];
  92. INT cwKey;
  93. INT cbKey;
  94. #ifndef DATABASE_FORMAT_CHANGE
  95. WORD rgwUpper[ JET_cbColumnMost / sizeof(WORD) ];
  96. #endif
  97. #ifndef _X86_
  98. /* convert pbColumn to aligned pointer for MIPS/Alpha builds
  99. /**/
  100. BYTE rgbColumn[JET_cbColumnMost];
  101. memcpy( rgbColumn, pbColumn, cbColumn );
  102. pbColumn = (BYTE *)&rgbColumn[0];
  103. #endif
  104. #ifdef DATABASE_FORMAT_CHANGE
  105. /* assert non-zero length unicode string
  106. /**/
  107. Assert( cbColumn =< JET_cbColumnMost );
  108. Assert( cbColumn > 0 );
  109. Assert( cbColumn % 2 == 0 );
  110. // UNDONE: after shipping with Daytona, remove this ifdef and
  111. // document database format change.
  112. cbKey = LCMapStringW(
  113. MAKELCID( langid, 0 ),
  114. #ifdef DAYTONA
  115. LCMAP_SORTKEY | NORM_IGNORECASE,
  116. #else
  117. LCMAP_SORTKEY | NORM_IGNORECASE | SORT_STRINGSORT,
  118. #endif
  119. (const unsigned short *)pbColumn,
  120. (int) cbColumn / sizeof(WORD),
  121. (unsigned short *)rgbKey,
  122. JET_cbUnicodeKeyMost );
  123. Assert( cbKey > 0 );
  124. if ( cbKey > cbMax )
  125. {
  126. err = wrnFLDKeyTooBig;
  127. *pcbSeg = cbMax;
  128. }
  129. else
  130. {
  131. Assert( err == JET_errSuccess );
  132. *pcbSeg = cbKey;
  133. }
  134. memcpy( rgbSeg, rgbKey, *pcbSeg );
  135. return err;
  136. #else
  137. /* assert non-zero length unicode string
  138. /**/
  139. Assert( cbColumn <= JET_cbColumnMost );
  140. Assert( cbColumn > 0 );
  141. Assert( cbColumn % 2 == 0 );
  142. cwKey = LCMapStringW(
  143. MAKELCID( langid, 0 ),
  144. LCMAP_UPPERCASE,
  145. (const unsigned short *) pbColumn,
  146. (INT) cbColumn / sizeof(WORD),
  147. rgwUpper,
  148. JET_cbColumnMost / sizeof(WORD) );
  149. Assert( cwKey == (INT)(cbColumn / sizeof(WORD)) );
  150. cbKey = LCMapStringW(
  151. MAKELCID( langid, 0 ),
  152. #ifdef DAYTONA
  153. LCMAP_SORTKEY,
  154. #else
  155. LCMAP_SORTKEY | SORT_STRINGSORT,
  156. #endif
  157. (const unsigned short *)rgwUpper,
  158. cbColumn / sizeof(WORD),
  159. (unsigned short *) rgbKey,
  160. JET_cbUnicodeKeyMost );
  161. Assert( cbKey > 0 );
  162. if ( cbKey > cbMax )
  163. {
  164. err = wrnFLDKeyTooBig;
  165. *pcbSeg = cbMax;
  166. }
  167. else
  168. {
  169. Assert( err == JET_errSuccess );
  170. *pcbSeg = cbKey;
  171. }
  172. memcpy( rgbSeg, rgbKey, *pcbSeg );
  173. return err;
  174. #endif
  175. }
  176. //+api------------------------------------------------------
  177. //
  178. // ErrSysCreateThread( ULONG (*pulfn)(), ULONG cbStack, LONG lThreadPriority );
  179. // ========================================================
  180. //
  181. // ErrSysCreateThread( ULONG (*pulfn)(), TID *ptid, ULONG cbStack );
  182. //
  183. // Creates a thread with the given stack size.
  184. //
  185. //----------------------------------------------------------
  186. ERR ErrSysCreateThread( ULONG (*pulfn)(), ULONG cbStackSize, LONG lThreadPriority, HANDLE *phandle )
  187. {
  188. HANDLE handle;
  189. TID tid;
  190. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  191. handle = (HANDLE) CreateThread( NULL,
  192. cbStackSize,
  193. (LPTHREAD_START_ROUTINE) pulfn,
  194. NULL,
  195. (DWORD) 0,
  196. (LPDWORD) &tid );
  197. if ( handle == 0 )
  198. return JET_errNoMoreThreads;
  199. if ( lThreadPriority == lThreadPriorityNormal )
  200. SetThreadPriority( handle, THREAD_PRIORITY_NORMAL );
  201. if ( lThreadPriority == lThreadPriorityEnhanced )
  202. SetThreadPriority( handle, THREAD_PRIORITY_ABOVE_NORMAL );
  203. if ( lThreadPriority == lThreadPriorityCritical )
  204. SetThreadPriority( handle, THREAD_PRIORITY_HIGHEST);
  205. /* return handle to thread.
  206. /**/
  207. *phandle = handle;
  208. return JET_errSuccess;
  209. }
  210. //+api------------------------------------------------------
  211. //
  212. // SysExitThread( ULONG ulExitCode );
  213. // ========================================================
  214. //
  215. // SysExitThread( ULONG ulExitCode );
  216. //
  217. // Exits thread.
  218. //
  219. //----------------------------------------------------------
  220. VOID SysExitThread( ULONG ulExitCode )
  221. {
  222. (VOID)ExitThread( ulExitCode );
  223. return;
  224. }
  225. //+api------------------------------------------------------
  226. //
  227. // FSysExitThread
  228. // ========================================================
  229. //
  230. // FSysExitThread( HANDLE handle );
  231. //
  232. // Returns fTrue if thread has exited.
  233. //
  234. //----------------------------------------------------------
  235. BOOL FSysExitThread( HANDLE handle )
  236. {
  237. BOOL f;
  238. DWORD dwExitCode;
  239. DWORD dw;
  240. f = GetExitCodeThread( handle, &dwExitCode );
  241. if ( !f )
  242. {
  243. dw = GetLastError();
  244. // UNDONE: handle error here
  245. Assert( fFalse );
  246. }
  247. return !(dwExitCode == STILL_ACTIVE);
  248. }
  249. //+api------------------------------------------------------
  250. //
  251. // ULONG UlSysThreadId( VOID )
  252. // ========================================================
  253. //
  254. // PARAMETERS
  255. //
  256. //----------------------------------------------------------
  257. ULONG UlSysThreadId( VOID )
  258. {
  259. return GetCurrentThreadId();
  260. }
  261. /* open a file that was opened as for write but shared to read.
  262. /**/
  263. ERR ErrSysOpenReadFile( CHAR *szFileName, HANDLE *phf )
  264. {
  265. *phf = CreateFile( szFileName,
  266. GENERIC_READ,
  267. FILE_SHARE_READ | FILE_SHARE_WRITE,
  268. 0,
  269. OPEN_EXISTING,
  270. FILE_ATTRIBUTE_NORMAL |
  271. FILE_FLAG_NO_BUFFERING |
  272. FILE_FLAG_RANDOM_ACCESS,
  273. 0 );
  274. if ( *phf == handleNil )
  275. {
  276. ERR err;
  277. err = ErrSYSIGetLastError( JET_errFileNotFound );
  278. return err;
  279. }
  280. return JET_errSuccess;
  281. }
  282. //+api------------------------------------------------------
  283. //
  284. // ErrSysOpenFile
  285. // ========================================================
  286. //
  287. // Open given file.
  288. //
  289. //----------------------------------------------------------
  290. ERR ErrSysOpenFile(
  291. CHAR *szFileName,
  292. HANDLE *phf,
  293. ULONG ulFileSize,
  294. BOOL fReadOnly,
  295. BOOL fOverlapped)
  296. {
  297. ERR err = JET_errSuccess;
  298. DWORD fdwAccess;
  299. DWORD fdwShare;
  300. DWORD fdwAttrsAndFlags;
  301. BOOL f;
  302. Assert( !ulFileSize || ulFileSize && !fReadOnly );
  303. *phf = handleNil;
  304. /* set access to read or read-write
  305. /**/
  306. if ( fReadOnly )
  307. fdwAccess = GENERIC_READ;
  308. else
  309. fdwAccess = GENERIC_READ | GENERIC_WRITE;
  310. /* do not allow sharing on database file
  311. /**/
  312. #ifdef JETSER
  313. fdwShare = FILE_SHARE_READ | FILE_SHARE_WRITE;
  314. #else
  315. fdwShare = FILE_SHARE_READ;
  316. #endif
  317. if ( fOverlapped )
  318. {
  319. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  320. FILE_FLAG_NO_BUFFERING |
  321. FILE_FLAG_WRITE_THROUGH |
  322. FILE_FLAG_RANDOM_ACCESS |
  323. FILE_FLAG_OVERLAPPED;
  324. }
  325. else
  326. {
  327. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  328. FILE_FLAG_NO_BUFFERING |
  329. FILE_FLAG_WRITE_THROUGH |
  330. FILE_FLAG_RANDOM_ACCESS;
  331. }
  332. if ( ulFileSize != 0L )
  333. {
  334. /* create a new file
  335. /**/
  336. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  337. FILE_FLAG_WRITE_THROUGH |
  338. FILE_FLAG_RANDOM_ACCESS;
  339. *phf = CreateFile( szFileName,
  340. fdwAccess,
  341. fdwShare,
  342. 0,
  343. CREATE_NEW,
  344. fdwAttrsAndFlags,
  345. 0 );
  346. if ( *phf == handleNil )
  347. {
  348. err = ErrSYSIGetLastError( JET_errFileNotFound );
  349. return err;
  350. }
  351. /* no overlapped, it does not work!
  352. /**/
  353. Call( ErrSysNewSize( *phf, ulFileSize, 0, fFalse ) );
  354. /* force log file pre-allocation to be effective
  355. /**/
  356. Assert(sizeof(HANDLE) == sizeof(HFILE));
  357. f = CloseHandle( (HANDLE) *phf );
  358. Assert( f );
  359. // UNDONE: is this still necessary in Daytona
  360. /* this bogus code works around an NT bug which
  361. /* causes network files not to have file usage
  362. /* restrictions reset until a GENERIC_READ file
  363. /* handle is closed.
  364. /**/
  365. if ( fOverlapped )
  366. {
  367. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  368. FILE_FLAG_NO_BUFFERING |
  369. FILE_FLAG_WRITE_THROUGH |
  370. FILE_FLAG_RANDOM_ACCESS |
  371. FILE_FLAG_OVERLAPPED;
  372. }
  373. else
  374. {
  375. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  376. FILE_FLAG_NO_BUFFERING |
  377. FILE_FLAG_WRITE_THROUGH |
  378. FILE_FLAG_RANDOM_ACCESS;
  379. }
  380. *phf = CreateFile( szFileName,
  381. GENERIC_READ,
  382. fdwShare,
  383. 0,
  384. OPEN_EXISTING,
  385. fdwAttrsAndFlags,
  386. 0 );
  387. if ( *phf == handleNil )
  388. {
  389. err = ErrSYSIGetLastError( JET_errFileNotFound );
  390. return err;
  391. }
  392. f = CloseHandle( (HANDLE) *phf );
  393. Assert( f );
  394. }
  395. if ( fOverlapped )
  396. {
  397. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  398. FILE_FLAG_NO_BUFFERING |
  399. FILE_FLAG_WRITE_THROUGH |
  400. FILE_FLAG_RANDOM_ACCESS |
  401. FILE_FLAG_OVERLAPPED;
  402. }
  403. else
  404. {
  405. fdwAttrsAndFlags = FILE_ATTRIBUTE_NORMAL |
  406. FILE_FLAG_NO_BUFFERING |
  407. FILE_FLAG_WRITE_THROUGH |
  408. FILE_FLAG_RANDOM_ACCESS;
  409. }
  410. *phf = CreateFile( szFileName,
  411. fdwAccess,
  412. fdwShare,
  413. 0,
  414. OPEN_EXISTING,
  415. fdwAttrsAndFlags,
  416. 0 );
  417. /* open in read_only mode if open in read_write mode failed
  418. /**/
  419. if ( *phf == handleNil && !fReadOnly && !ulFileSize )
  420. {
  421. /* try to open file read only
  422. /**/
  423. fdwAccess = GENERIC_READ;
  424. *phf = CreateFile( szFileName,
  425. fdwAccess,
  426. fdwShare,
  427. 0,
  428. OPEN_EXISTING,
  429. fdwAttrsAndFlags,
  430. 0 );
  431. err = JET_wrnFileOpenReadOnly;
  432. }
  433. /* if file could not be opened, return NULL file handle.
  434. /**/
  435. if ( *phf == handleNil )
  436. {
  437. err = ErrSYSIGetLastError( JET_errFileNotFound );
  438. return err;
  439. }
  440. #if 0
  441. #ifdef DEBUG
  442. else
  443. {
  444. SysGetDriveGeometry( *phf );
  445. }
  446. #endif
  447. #endif
  448. HandleError:
  449. if ( err < 0 && *phf != handleNil )
  450. {
  451. f = CloseHandle( (HANDLE) *phf );
  452. Assert(f);
  453. *phf = handleNil;
  454. }
  455. return err;
  456. }
  457. //+api------------------------------------------------------
  458. //
  459. // ErrSysDeleteFile
  460. // ========================================================
  461. //
  462. // ERR ErrSysDeleteFile( const CHAR *szFileName )
  463. //
  464. // Delete given file.
  465. //
  466. //----------------------------------------------------------
  467. ERR ErrSysDeleteFile( const CHAR *szFileName )
  468. {
  469. if ( DeleteFile( szFileName ) )
  470. return JET_errSuccess;
  471. return JET_errFileNotFound;
  472. }
  473. //+api------------------------------------------------------
  474. //
  475. // ERR ErrSysNewSize( HANDLE hf, ULONG ulSize, ULONG ulSizeHigh, BOOL fOverlapped )
  476. // ========================================================
  477. //
  478. // Resize database file. Not semaphore protected as new size
  479. // operation will not conflict with chgfileptr, read or write.
  480. //
  481. // PARAMETERS
  482. // hf file handle
  483. // cpg new size of database file in pages
  484. //
  485. //----------------------------------------------------------
  486. #if 0
  487. // UNDONE: this scheme of write 1024 bytes before the end of file will not work
  488. // UNDONE: for shrinking files.
  489. ERR ErrSysNewSize( HANDLE hf, ULONG ulFileSize, ULONG ulFileSizeHigh, BOOL fOverlapped )
  490. {
  491. #if 0
  492. ERR err = JET_errSuccess;
  493. INT cbT;
  494. ULONG ul;
  495. #define cbSec 1024
  496. /* memory must be 16-byte aligned and mulitple of 1024 bytes
  497. /**/
  498. BYTE *pb = (BYTE *) PvSysAllocAndCommit( cbSec + 15 );
  499. BYTE *pbAligned = (BYTE *)( (ULONG)(pb + 15) & ~0x0f );
  500. if ( pb == NULL )
  501. return JET_errOutOfMemory;
  502. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  503. if ( ulFileSize >= cbSec )
  504. {
  505. ulFileSize -= cbSec;
  506. }
  507. else
  508. {
  509. Assert( ulFileSize == 0 );
  510. ulFileSizeHigh--;
  511. ulFileSize = (ULONG) ~cbSec + 1;
  512. }
  513. ul = SetFilePointer( (HANDLE) hf, ulFileSize, &ulFileSizeHigh, FILE_BEGIN );
  514. if ( ul != ulFileSize )
  515. {
  516. // UNDONE: check for other errors
  517. return JET_errDiskFull;
  518. }
  519. /* the mask bits are to satisfy the 16-byte boundary alignment in MIPS
  520. /**/
  521. (VOID)ErrSysWriteBlock( hf, pbAligned, cbSec, &cbT );
  522. if ( GetLastError() == ERROR_DISK_FULL )
  523. err = JET_errDiskFull;
  524. if ( pb != NULL )
  525. SysFree( pb );
  526. return err;
  527. #else
  528. int cb;
  529. ULONG ul;
  530. /* the extra 15 bytes are for the sake of 16-byte
  531. /* boundary alignment in MIPS
  532. /**/
  533. #define cbSec 1024 // must be same as in page.h
  534. STATIC BYTE rgb[cbSec + 15];
  535. Assert(sizeof(HANDLE) == sizeof(HFILE));
  536. if ( ulFileSize >= cbSec )
  537. ulFileSize -= cbSec;
  538. else
  539. {
  540. Assert( ulFileSize == 0 );
  541. ulFileSizeHigh--;
  542. ulFileSize = (ULONG) ~cbSec + 1;
  543. }
  544. ul = SetFilePointer(
  545. (HANDLE) hf, ulFileSize, &ulFileSizeHigh, FILE_BEGIN );
  546. if ( ul != ulFileSize )
  547. goto CheckError;
  548. /* the mask bits are to satisfy the 16-byte boundary alignment in MIPS
  549. /**/
  550. (void) ErrSysWriteBlock( hf,(BYTE *) ( (ULONG)(rgb+15) & ~0x0f ), cbSec, &cb );
  551. if ( GetLastError() == ERROR_DISK_FULL )
  552. return JET_errDiskFull;
  553. return JET_errSuccess;
  554. CheckError:
  555. if ( GetLastError() == ERROR_DISK_FULL )
  556. return JET_errDiskFull;
  557. return JET_errDiskIO;
  558. #endif
  559. }
  560. #endif
  561. /* the following function should work -- if FAT FS bug fixed
  562. /**/
  563. ERR ErrSysNewSize( HANDLE hf, ULONG ulSize, ULONG ulSizeHigh, BOOL fOverlapped )
  564. {
  565. ULONG ul;
  566. BOOL f;
  567. ul = SetFilePointer( hf, ulSize, &ulSizeHigh, FILE_BEGIN );
  568. if ( ul != ulSize )
  569. goto HandleError;
  570. f = SetEndOfFile( hf );
  571. if ( !( f ) )
  572. goto HandleError;
  573. return JET_errSuccess;
  574. HandleError:
  575. if ( GetLastError() == ERROR_DISK_FULL )
  576. return JET_errDiskFull;
  577. return JET_errDiskIO;
  578. }
  579. //+api------------------------------------------------------
  580. //
  581. // ErrSysCloseFile
  582. // =========================================================
  583. //
  584. // ERR ErrSysCloseFile( HANDLE hf )
  585. //
  586. // Close file.
  587. //
  588. //----------------------------------------------------------
  589. ERR ErrSysCloseHandle( HANDLE hf )
  590. {
  591. BOOL f;
  592. Assert(sizeof(HANDLE) == sizeof(HFILE));
  593. f = CloseHandle( (HANDLE) hf );
  594. if ( !f )
  595. return JET_errFileClose;
  596. return JET_errSuccess;
  597. }
  598. LOCAL ERR ErrCheckError( VOID )
  599. {
  600. DWORD dw = GetLastError();
  601. if ( dw == ERROR_IO_PENDING )
  602. return JET_errSuccess;
  603. if ( dw == ERROR_INVALID_USER_BUFFER ||
  604. dw == ERROR_NOT_ENOUGH_MEMORY )
  605. return JET_errTooManyIO;
  606. if ( dw == ERROR_DISK_FULL )
  607. return JET_errDiskFull;
  608. if ( dw == ERROR_HANDLE_EOF )
  609. return JET_errDiskIO;
  610. /* if this assert is hit, then we need another error code
  611. /**/
  612. Assert( fFalse );
  613. return JET_errDiskIO;
  614. }
  615. //+api------------------------------------------------------
  616. //
  617. // ErrSysReadBlock( hf, pvBuf, cbBuf, pcbRead )
  618. // ========================================================
  619. //
  620. // ERR ErrSysReadBlock( hf, pvBuf, cbBuf, pcbRead )
  621. //
  622. // Reads cbBuf bytes of data into pvBuf. Returns error if DOS error
  623. // or if less than expected number of bytes retured.
  624. //
  625. //----------------------------------------------------------
  626. ERR ErrSysReadBlock( HANDLE hf, VOID *pvBuf, UINT cbBuf, UINT *pcbRead )
  627. {
  628. BOOL f;
  629. INT msec = 1;
  630. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  631. IssueRead:
  632. f = ReadFile( (HANDLE) hf, pvBuf, cbBuf, pcbRead, NULL );
  633. if ( f )
  634. {
  635. if ( cbBuf != *pcbRead )
  636. return JET_errDiskIO;
  637. else
  638. return JET_errSuccess;
  639. }
  640. else
  641. {
  642. ERR err = ErrCheckError();
  643. if ( err == JET_errTooManyIO )
  644. {
  645. msec <<= 1;
  646. Sleep( msec - 1 );
  647. goto IssueRead;
  648. }
  649. else
  650. return err;
  651. }
  652. }
  653. //+api------------------------------------------------------
  654. //
  655. // ERR ErrSysWriteBlock( hf, pvBuf, cbBuf, pcbWritten )
  656. // =========================================================
  657. //
  658. // ERR ErrSysWriteBlock( hf, pvBuf, cbBuf, pcbWritten )
  659. //
  660. // Writes cbBuf bytes from pbBuf to file hf.
  661. //
  662. //----------------------------------------------------------
  663. ERR ErrSysWriteBlock( HANDLE hf, VOID *pvBuf, UINT cbBuf, UINT *pcbWritten )
  664. {
  665. BOOL f;
  666. INT msec = 1;
  667. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  668. IssueWrite:
  669. f = WriteFile( (HANDLE) hf, pvBuf, cbBuf, pcbWritten, NULL );
  670. if ( f )
  671. {
  672. if ( cbBuf != *pcbWritten )
  673. {
  674. if ( GetLastError() == ERROR_DISK_FULL )
  675. return JET_errDiskFull;
  676. else
  677. return JET_errDiskIO;
  678. }
  679. else
  680. return JET_errSuccess;
  681. }
  682. else
  683. {
  684. ERR err = ErrCheckError();
  685. if ( err == JET_errTooManyIO )
  686. {
  687. msec <<= 1;
  688. Sleep(msec - 1);
  689. goto IssueWrite;
  690. }
  691. else
  692. return err;
  693. }
  694. }
  695. //+api------------------------------------------------------
  696. //
  697. // ErrSysReadBlockOverlapped( hf, pvBuf, cbBuf, pcbRead )
  698. // =========================================================
  699. //
  700. // ERR ErrSysReadBlock( hf, pvBuf, cbBuf, pcbRead )
  701. //
  702. // Reads cbBuf bytes of data into pvBuf. Returns error if DOS error
  703. // or if less than expected number of bytes retured.
  704. //
  705. //----------------------------------------------------------
  706. ERR ErrSysReadBlockOverlapped(
  707. HANDLE hf,
  708. VOID *pvBuf,
  709. UINT cbBuf,
  710. DWORD *pcbRead,
  711. OLP *polp)
  712. {
  713. BOOL f;
  714. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  715. Assert( sizeof(OLP) == sizeof(OVERLAPPED) );
  716. f = ReadFile( (HANDLE) hf, pvBuf, cbBuf, pcbRead, (OVERLAPPED *) polp );
  717. if ( f )
  718. return JET_errSuccess;
  719. else
  720. return ErrCheckError();
  721. }
  722. //+api------------------------------------------------------
  723. //
  724. // Err ErrSysWriteBlockOverlapped( hf, pvBuf, cbBuf, pcbWritten )
  725. // =========================================================
  726. //
  727. // ERR ErrSysWriteBlock( hf, pvBuf, cbBuf, pcbWritten )
  728. //
  729. // Writes cbBuf bytes from pbBuf to file hf.
  730. //
  731. //----------------------------------------------------------
  732. ERR ErrSysWriteBlockOverlapped(
  733. HANDLE hf,
  734. VOID *pvBuf,
  735. UINT cbBuf,
  736. DWORD *pcbWritten,
  737. OLP *polp)
  738. {
  739. BOOL f;
  740. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  741. Assert( sizeof(OLP) == sizeof(OVERLAPPED) );
  742. f = WriteFile( (HANDLE) hf, pvBuf, cbBuf, pcbWritten, (OVERLAPPED *)polp );
  743. if ( f )
  744. {
  745. return JET_errSuccess;
  746. }
  747. else
  748. {
  749. return ErrCheckError();
  750. }
  751. }
  752. //+api------------------------------------------------------
  753. //
  754. // ErrSysReadBlockEx( hf, pvBuf, cbBuf, pcbRead )
  755. // ========================================================
  756. //
  757. // ERR ErrSysReadBlock( hf, pvBuf, cbBuf, pcbRead )
  758. //
  759. // Reads cbBuf bytes of data into pvBuf. Returns error if DOS error
  760. // or if less than expected number of bytes retured.
  761. //
  762. //----------------------------------------------------------
  763. ERR ErrSysReadBlockEx(
  764. HANDLE hf,
  765. VOID *pvBuf,
  766. UINT cbBuf,
  767. OLP *polp,
  768. VOID *pfnCompletion)
  769. {
  770. BOOL f;
  771. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  772. Assert( sizeof(OLP) == sizeof(OVERLAPPED) );
  773. f = ReadFileEx( (HANDLE) hf,
  774. pvBuf,
  775. cbBuf,
  776. (OVERLAPPED *) polp,
  777. (LPOVERLAPPED_COMPLETION_ROUTINE) pfnCompletion );
  778. if ( f )
  779. return JET_errSuccess;
  780. else
  781. return ErrCheckError();
  782. }
  783. //+api------------------------------------------------------
  784. //
  785. // ERR ErrSysWriteBlockEx( hf, pvBuf, cbBuf, pcbWritten )
  786. // ========================================================
  787. //
  788. // ERR ErrSysWriteBlock( hf, pvBuf, cbBuf, pcbWritten )
  789. //
  790. // Writes cbBuf bytes from pbBuf to file hf.
  791. //
  792. //----------------------------------------------------------
  793. ERR ErrSysWriteBlockEx(
  794. HANDLE hf,
  795. VOID *pvBuf,
  796. UINT cbBuf,
  797. OLP *polp,
  798. VOID *pfnCompletion )
  799. {
  800. BOOL f;
  801. ERR err;
  802. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  803. Assert( sizeof(OLP) == sizeof(OVERLAPPED) );
  804. f = WriteFileEx( (HANDLE) hf,
  805. pvBuf,
  806. cbBuf,
  807. (OVERLAPPED *)polp,
  808. (LPOVERLAPPED_COMPLETION_ROUTINE)pfnCompletion );
  809. if ( f )
  810. err = JET_errSuccess;
  811. else
  812. err = ErrCheckError();
  813. return err;
  814. }
  815. ERR ErrSysGetOverlappedResult(
  816. HANDLE hf,
  817. OLP *polp,
  818. UINT *pcb,
  819. BOOL fWait)
  820. {
  821. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  822. Assert( sizeof(OLP) == sizeof(OVERLAPPED) );
  823. if ( GetOverlappedResult( (HANDLE) hf, (OVERLAPPED *)polp, pcb, fWait ) )
  824. return JET_errSuccess;
  825. if ( GetLastError() == ERROR_DISK_FULL )
  826. return JET_errDiskFull;
  827. return JET_errDiskIO;
  828. }
  829. //+api------------------------------------------------------
  830. //
  831. // VOID SysChgFilePtr( HANDLE hf, LONG lRel, LONG *plRelHigh, ULONG ulRef, ULONG *pul )
  832. // =========================================================
  833. //
  834. // Changes file hf pointer to position lRef relative to position :
  835. //
  836. // wRef FILE_BEGIN file beginnging
  837. //
  838. //----------------------------------------------------------
  839. VOID SysChgFilePtr( HANDLE hf, LONG lRel, LONG *plRelHigh, ULONG ulRef, ULONG *pul )
  840. {
  841. Assert( sizeof(HANDLE) == sizeof(HFILE) );
  842. *pul = SetFilePointer( (HANDLE)hf, lRel, plRelHigh, ulRef );
  843. Assert( ulRef != FILE_BEGIN || *pul == (ULONG)lRel );
  844. return;
  845. }
  846. //+api------------------------------------------------------
  847. //
  848. // ErrSysMove( CHAR *szFrom, CHAR *szTo )
  849. // =========================================================
  850. //
  851. // ERR ErrSysMove( CHAR *szFrom, CHAR *szTo )
  852. //
  853. // Renames file szFrom to file name szTo.
  854. //
  855. //----------------------------------------------------------
  856. ERR ErrSysMove( CHAR *szFrom, CHAR *szTo )
  857. {
  858. if ( MoveFile( szFrom, szTo ) )
  859. return JET_errSuccess;
  860. else
  861. return JET_errFileAccessDenied;
  862. }
  863. //+api------------------------------------------------------
  864. //
  865. // ERR ErrSysCopy( CHAR *szFrom, CHAR *szTo, BOOL fFailIfExists )
  866. // ========================================================
  867. //
  868. // Copies file szFrom to file name szTo.
  869. // If szTo already exists, the function either fails or overwrites
  870. // the existing file, depending on the flag fFailIfExists
  871. //
  872. //----------------------------------------------------------
  873. ERR ErrSysCopy( CHAR *szFrom, CHAR *szTo, BOOL fFailIfExists )
  874. {
  875. if ( CopyFile( szFrom, szTo, fFailIfExists ) )
  876. return JET_errSuccess;
  877. else
  878. return JET_errFileAccessDenied;
  879. }
  880. //+api------------------------------------------------------
  881. //
  882. // ERR ErrSysGetComputerName( CHAR *sz, INT *pcb )
  883. // =========================================================
  884. //
  885. //----------------------------------------------------------
  886. ERR ErrSysGetComputerName( CHAR *sz, INT *pcb)
  887. {
  888. if ( GetComputerName( sz, pcb ) )
  889. return JET_errSuccess;
  890. else
  891. return JET_errNoComputerName;
  892. }
  893. //+api------------------------------------------------------
  894. //
  895. // SysSleep( ULONG ulTime )
  896. // =========================================================
  897. //
  898. // ERR ErrSysSleep( ULONG ulTime )
  899. //
  900. // Waits ulTime milliseconds.
  901. //
  902. //----------------------------------------------------------
  903. VOID SysSleep( ULONG ulTime )
  904. {
  905. Sleep( ulTime );
  906. return;
  907. }
  908. //+api------------------------------------------------------
  909. //
  910. // VOID SysSleepEx( ULONG ulTime )
  911. // ========================================================
  912. //
  913. // Waits ulTime milliseconds.
  914. //
  915. //----------------------------------------------------------
  916. VOID SysSleepEx( ULONG ulTime, BOOL fAlert )
  917. {
  918. SleepEx( ulTime, fAlert );
  919. return;
  920. }
  921. //+api------------------------------------------------------
  922. //
  923. // HANDLE SysGetCurrentTask( VOID )
  924. // ========================================================
  925. //
  926. // Gets curren task handle for Windows.
  927. //
  928. //----------------------------------------------------------
  929. HANDLE SysGetCurrentTask( VOID )
  930. {
  931. return LongToHandle(GetCurrentProcessId());
  932. }
  933. //+api------------------------------------------------------
  934. //
  935. // SysNormText( CHAR *rgchText, INT cchText, CHAR *rgchNorm, INT cchNorm, INT *pchNorm )
  936. // =========================================================
  937. //
  938. // VOID SysNormText( CHAR *rgchText, INT cchText, CHAR *rgchNorm, INT cchNorm, INT *pchNorm )
  939. //
  940. // Normalizes text string.
  941. //
  942. //----------------------------------------------------------
  943. VOID SysNormText( CHAR *rgchText, INT cchText, BYTE *rgbNorm, INT cbNorm, INT *pbNorm )
  944. {
  945. ERR err;
  946. Assert( cbNorm <= JET_cbKeyMost );
  947. err = ErrSysNormText( rgchText, cchText, cbNorm, rgbNorm, pbNorm );
  948. Assert( err == JET_errSuccess || err == wrnFLDKeyTooBig );
  949. return;
  950. }
  951. //+api------------------------------------------------------
  952. //
  953. // VOID SysCmpText( const CHAR *sz1, const CHAR sz2 )
  954. // ========================================================
  955. //
  956. // Compares two unnormalized text strings by first normalizing them
  957. // and then comparing them.
  958. //
  959. // Returns: > 0 if sz1 > sz2
  960. // == 0 if sz1 == sz2
  961. // < 0 if sz1 < sz2
  962. //
  963. //----------------------------------------------------------
  964. INT SysCmpText( const CHAR *sz1, const CHAR *sz2 )
  965. {
  966. ERR err;
  967. INT cch1;
  968. INT cch2;
  969. CHAR rgch1Norm[ JET_cbKeyMost ];
  970. INT cch1Norm;
  971. CHAR rgch2Norm[ JET_cbKeyMost ];
  972. INT cch2Norm;
  973. INT cchDiff;
  974. INT iCmp;
  975. /* get text string lengths
  976. /**/
  977. cch1 = strlen( sz1 );
  978. Assert( cch1 <= JET_cbKeyMost );
  979. cch2 = strlen( sz2 );
  980. Assert( cch2 <= JET_cbKeyMost );
  981. err = ErrSysNormText( sz1, cch1, JET_cbKeyMost, rgch1Norm, &cch1Norm );
  982. Assert( err == JET_errSuccess || err == wrnFLDKeyTooBig );
  983. err = ErrSysNormText( sz2, cch2, JET_cbKeyMost, rgch2Norm, &cch2Norm );
  984. Assert( err == JET_errSuccess || err == wrnFLDKeyTooBig );
  985. cchDiff = cch1Norm - cch2Norm;
  986. iCmp = memcmp( rgch1Norm, rgch2Norm, cchDiff < 0 ? cch1Norm : cch2Norm );
  987. return iCmp ? iCmp : cchDiff;
  988. }
  989. VOID SysStringCompare( char __far *pb1,
  990. unsigned long cb1,
  991. char __far *pb2,
  992. unsigned long cb2,
  993. unsigned long sort,
  994. long __far *plResult )
  995. {
  996. CHAR rgb1[JET_cbColumnMost + 1];
  997. CHAR rgb2[JET_cbColumnMost + 1];
  998. /* ensure NULL terminated
  999. /**/
  1000. memcpy( rgb1, pb1, min( JET_cbColumnMost, cb1 ) );
  1001. rgb1[ min( JET_cbColumnMost, cb1 ) ] = '\0';
  1002. memcpy( rgb2, pb2, min( JET_cbColumnMost, cb2 ) );
  1003. rgb2[ min( JET_cbColumnMost, cb2 ) ] = '\0';
  1004. *plResult = SysCmpText( (const char *)rgb1, (const char *)rgb2 );
  1005. return;
  1006. }
  1007. ERR ErrSysNormText(
  1008. const BYTE *pbText,
  1009. INT cbText,
  1010. INT cbKeyBufLeft,
  1011. BYTE *pbNorm,
  1012. INT *pcbNorm )
  1013. {
  1014. #ifdef DBCS
  1015. INT iLoop;
  1016. #endif
  1017. BYTE *pbNormBegin = pbNorm;
  1018. BYTE rgbAccent[ (JET_cbKeyMost + 1) / 2 + 1 ];
  1019. BYTE *pbAccent = rgbAccent;
  1020. BYTE *pbBeyondKeyBufLeft = pbNorm + cbKeyBufLeft;
  1021. const BYTE *pbBeyondText;
  1022. const BYTE *pbTextLastChar = pbText + cbText - 1;
  1023. BYTE bAccentTmp = 0;
  1024. if (cbKeyBufLeft > 0)
  1025. *pbNorm = '\0';
  1026. while ( *pbTextLastChar-- == ' ' )
  1027. cbText--;
  1028. /* add one back to the pointer
  1029. /**/
  1030. pbTextLastChar++;
  1031. Assert( pbTextLastChar == pbText + cbText - 1 );
  1032. pbBeyondText = pbTextLastChar + 1;
  1033. while ( pbText < pbBeyondText && pbNorm < pbBeyondKeyBufLeft )
  1034. {
  1035. #ifdef DBCS
  1036. if ( pbText < pbTextLastChar )
  1037. {
  1038. /* two or more char remaining
  1039. /* check for double char to single char
  1040. /* for translation tables of some languages
  1041. /**/
  1042. for ( iLoop = 0; iLoop < cchDouble; iLoop++ )
  1043. {
  1044. BYTE bFirst = *pbText;
  1045. if ( bFirst == BFirstByteOfDouble(iLoop)
  1046. && *(pbText + 1) == BSecondByteOfDouble(iLoop) )
  1047. {
  1048. /* don't do a "pbText++" above
  1049. /* do a double to single conversion
  1050. /**/
  1051. *pbNorm++ = BThirdByteOfDouble(iLoop);
  1052. /* pointing at char for accent map
  1053. /**/
  1054. pbText++;
  1055. /* no need to loop any more
  1056. /**/
  1057. break;
  1058. }
  1059. }
  1060. }
  1061. else
  1062. #endif
  1063. {
  1064. BYTE bTmp;
  1065. /* do a single to single char conversion
  1066. /**/
  1067. *pbNorm = bTmp = BGetTranslation(*pbText);
  1068. if ( bTmp >= 250 )
  1069. {
  1070. /* do a single to double char conversion
  1071. /**/
  1072. *pbNorm++ = BFirstByteForSingle(bTmp);
  1073. if ( pbNorm < pbBeyondKeyBufLeft )
  1074. *pbNorm = BSecondByteForSingle(bTmp);
  1075. else
  1076. break;
  1077. /* no need to do accent any more,
  1078. /* so break out of while loop
  1079. /**/
  1080. }
  1081. pbNorm++;
  1082. }
  1083. /* at this point, pbText should point to the char for accent mapping
  1084. /**/
  1085. /* do accent now
  1086. /* the side effect is to increment pbText
  1087. /**/
  1088. if ( bAccentTmp == 0 )
  1089. {
  1090. /* first nibble of accent
  1091. /**/
  1092. bAccentTmp = (BYTE)( BGetAccent( *pbText++ ) << 4 );
  1093. Assert( bAccentTmp > 0 );
  1094. }
  1095. else
  1096. {
  1097. /* already has first nibble
  1098. /**/
  1099. *pbAccent++ = BGetAccent(*pbText++) | bAccentTmp;
  1100. bAccentTmp = 0;
  1101. /* reseting the accents
  1102. /**/
  1103. }
  1104. }
  1105. if ( pbNorm < pbBeyondKeyBufLeft )
  1106. {
  1107. /* need to do accent
  1108. /**/
  1109. *pbNorm++ = 0;
  1110. /* key-accent separator
  1111. /**/
  1112. if ( bAccentTmp != 0 && bAccentTmp != 0x10 )
  1113. {
  1114. /* an trailing accent which is not 0x10 should be kept
  1115. /**/
  1116. *pbAccent++ = bAccentTmp;
  1117. }
  1118. /* at this point, pbAccent is pointing at one char
  1119. /* beyond the accent bytes. clear up trailing 0x11's
  1120. /**/
  1121. while (--pbAccent >= rgbAccent && *pbAccent == 0x11)
  1122. ;
  1123. *( pbAccent + 1 ) = 0;
  1124. /* append accent to text.
  1125. /* copy bytes up to and including '\0'.
  1126. /* case checked for rgbAccent being empty.
  1127. /**/
  1128. pbAccent = rgbAccent;
  1129. Assert( pbNorm <= pbBeyondKeyBufLeft );
  1130. while ( pbNorm < pbBeyondKeyBufLeft && (*pbNorm++ = *pbAccent++ ) )
  1131. ;
  1132. }
  1133. /* compute the length of the normalized key and return
  1134. /**/
  1135. *pcbNorm = (INT)(pbNorm - pbNormBegin);
  1136. if ( pbNorm < pbBeyondKeyBufLeft )
  1137. return JET_errSuccess;
  1138. else
  1139. return wrnFLDKeyTooBig;
  1140. /* UNDONE: even if >=, maybe
  1141. /* just fit, but not "too big"
  1142. /* Do we want KeyBufFull or TooBig?
  1143. /**/
  1144. }
  1145. #if 0
  1146. VOID SysGetDriveGeometry( HANDLE handle )
  1147. {
  1148. BOOL f;
  1149. DISK_GEOMETRY disk_geometry;
  1150. DWORD cb;
  1151. f = DeviceIoControl( handle,
  1152. IOCTL_DISK_GET_DRIVE_GEOMETRY,
  1153. NULL,
  1154. 0,
  1155. &disk_geometry,
  1156. sizeof(disk_geometry),
  1157. &cb,
  1158. NULL );
  1159. Assert( f == fTrue );
  1160. return;
  1161. }
  1162. #endif
  1163. //==========================================================
  1164. // Memory Routines
  1165. //==========================================================
  1166. #ifdef DEBUG
  1167. #ifdef MEM_CHECK
  1168. #define icalMax 10000
  1169. typedef struct {
  1170. VOID *pv;
  1171. ULONG cbAlloc;
  1172. } CAL;
  1173. STATIC CAL rgcal[icalMax];
  1174. STATIC ULONG cbAllocTotal = 0;
  1175. STATIC ULONG cblockAlloc = 0;
  1176. STATIC ULONG cblockFree = 0;
  1177. STATIC BOOL fInit = fFalse;
  1178. LOCAL VOID UtilIInsertAlloc( VOID *pv, ULONG cbAlloc )
  1179. {
  1180. INT ical;
  1181. /* do not track failed allocations
  1182. /**/
  1183. if ( pv == NULL )
  1184. return;
  1185. /* initialize array of allocations if not yet initialized.
  1186. /**/
  1187. if ( fInit == fFalse )
  1188. {
  1189. memset( rgcal, '\0', sizeof(rgcal) );
  1190. fInit = fTrue;
  1191. }
  1192. for ( ical = 0; ical < icalMax; ical++ )
  1193. {
  1194. if ( rgcal[ical].pv == NULL )
  1195. {
  1196. rgcal[ical].pv = pv;
  1197. rgcal[ical].cbAlloc = cbAlloc;
  1198. cbAllocTotal += cbAlloc;
  1199. cblockAlloc++;
  1200. return;
  1201. }
  1202. }
  1203. Assert( fFalse );
  1204. }
  1205. LOCAL VOID UtilIDeleteAlloc( VOID *pv )
  1206. {
  1207. INT ical;
  1208. Assert( pv != NULL );
  1209. Assert( fInit == fTrue );
  1210. for ( ical = 0; ical < icalMax; ical++ )
  1211. {
  1212. if ( rgcal[ical].pv == pv )
  1213. {
  1214. cblockFree++;
  1215. cbAllocTotal -= rgcal[ical].cbAlloc;
  1216. rgcal[ical].pv = NULL;
  1217. rgcal[ical].cbAlloc = 0;
  1218. return;
  1219. }
  1220. }
  1221. AssertSz( fFalse, "Attempt to Free a bad pointer" );
  1222. }
  1223. #else
  1224. #define UtilIInsertAlloc( pv, cb )
  1225. #define UtilIDeleteAlloc( pv )
  1226. #endif
  1227. VOID *SAlloc( ULONG cbBlock )
  1228. {
  1229. VOID *pv;
  1230. #ifdef RFS2
  1231. if ( !RFSAlloc( SAllocMemory ) )
  1232. return NULL;
  1233. #endif
  1234. pv = malloc(cbBlock);
  1235. UtilIInsertAlloc( pv, cbBlock );
  1236. return pv;
  1237. }
  1238. VOID OSSFree( void *pv )
  1239. {
  1240. UtilIDeleteAlloc( pv );
  1241. free(pv);
  1242. }
  1243. VOID *LAlloc( ULONG cBlock, USHORT cbBlock )
  1244. {
  1245. VOID *pv;
  1246. #ifdef RFS2
  1247. if ( !RFSAlloc( LAllocMemory ) )
  1248. return NULL;
  1249. #endif
  1250. pv = malloc(cBlock * cbBlock);
  1251. UtilIInsertAlloc( pv, cBlock * cbBlock );
  1252. return pv;
  1253. }
  1254. VOID OSLFree( void *pv )
  1255. {
  1256. UtilIDeleteAlloc( pv );
  1257. free(pv);
  1258. }
  1259. VOID *PvSysAlloc( ULONG dwSize )
  1260. {
  1261. VOID *pv;
  1262. #ifdef RFS2
  1263. if ( !RFSAlloc( PvSysAllocMemory ) )
  1264. return NULL;
  1265. #endif
  1266. pv = VirtualAlloc( NULL, dwSize, MEM_RESERVE, PAGE_READWRITE );
  1267. UtilIInsertAlloc( pv, dwSize );
  1268. return pv;
  1269. }
  1270. VOID *PvSysCommit( VOID *pv, ULONG ulSize )
  1271. {
  1272. VOID *pvCommit;
  1273. pvCommit = VirtualAlloc( pv, ulSize, MEM_COMMIT, PAGE_READWRITE );
  1274. return pvCommit;
  1275. }
  1276. VOID SysFree( VOID *pv )
  1277. {
  1278. UtilIDeleteAlloc( pv );
  1279. VirtualFree( pv, 0, MEM_RELEASE );
  1280. return;
  1281. }
  1282. #else
  1283. VOID *PvSysAlloc( ULONG dwSize )
  1284. {
  1285. return VirtualAlloc( NULL, dwSize, MEM_RESERVE, PAGE_READWRITE );
  1286. }
  1287. VOID *PvSysCommit( VOID *pv, ULONG ulSize )
  1288. {
  1289. return VirtualAlloc( pv, ulSize, MEM_COMMIT, PAGE_READWRITE );
  1290. }
  1291. VOID SysFree( VOID *pv )
  1292. {
  1293. VirtualFree( pv, 0, MEM_RELEASE );
  1294. return;
  1295. }
  1296. #endif
  1297. VOID *PvSysAllocAndCommit( ULONG ulSize )
  1298. {
  1299. VOID *pv;
  1300. if ( ( pv = PvSysAlloc( ulSize ) ) == NULL )
  1301. return pv;
  1302. if ( PvSysCommit( pv, ulSize ) == NULL )
  1303. {
  1304. SysFree( pv );
  1305. return NULL;
  1306. }
  1307. return pv;
  1308. }
  1309. VOID SysTerm( VOID )
  1310. {
  1311. #ifdef MEM_CHECK
  1312. ULONG cbTrueAllocTotal = cbAllocTotal; /* Alloc total not counting critJet */
  1313. INT ical;
  1314. Assert( critJet != NULL );
  1315. /* find critJet in store and delete size from true alloc total */
  1316. for ( ical = 0; ical < icalMax; ical++ )
  1317. {
  1318. if ( rgcal[ical].pv == critJet )
  1319. {
  1320. cbTrueAllocTotal -= rgcal[ical].cbAlloc;
  1321. break;
  1322. }
  1323. }
  1324. if (cbTrueAllocTotal != 0)
  1325. {
  1326. char szAllocTotal[256];
  1327. sprintf( szAllocTotal, "%ld bytes unfreed memory on termination.", cbTrueAllocTotal );
  1328. AssertFail((const char *)szAllocTotal, szAssertFilename, __LINE__ );
  1329. }
  1330. #endif
  1331. return;
  1332. }
  1333. VOID SysDebugBreak( VOID )
  1334. {
  1335. DebugBreak();
  1336. }