Windows-Server-2003/net/jet500/xjet/inc/utilw32.h

532 lines
14 KiB
C

#ifndef _UTILW32_H
#define _UTILW32_H
// Redirect Asserts in inline code to seem to fire from this file
#define szAssertFilename __FILE__
#ifdef DEBUG
ERR ErrERRCheck( ERR err );
#else
#define ErrERRCheck( err ) ( err )
#endif
// Init / Term
ERR ErrUtilInit(void);
VOID UtilTerm(void);
// Miscellaneous
STATIC INLINE DWORD DwUtilGetLastError( void ) { return GetLastError(); }
STATIC INLINE ULONG UlUtilGetTickCount( VOID ) { return GetTickCount(); }
STATIC INLINE QWORD QwUtilPerfCount( VOID )
{
QWORDX qwx;
if ( !QueryPerformanceCounter( (LARGE_INTEGER *) &qwx.qw ) )
{
qwx.h = GetTickCount();
qwx.l = 0;
}
return qwx.qw;
}
STATIC INLINE QWORD QwUtilPerfCountFrq( VOID )
{
QWORDX qwx;
if ( !QueryPerformanceFrequency( (LARGE_INTEGER *) &qwx.qw ) )
{
qwx.h = 1000;
qwx.l = 0;
}
return qwx.qw;
}
STATIC INLINE double DblUtilPerfElapsedTime( QWORD qwStartCount )
{
return (signed __int64) ( QwUtilPerfCount() - qwStartCount )
/ (double) (signed __int64) QwUtilPerfCountFrq();
}
STATIC INLINE double DblUtilPerfElapsedTime2( QWORD qwStartCount, QWORD qwEndCount )
{
return (signed __int64) ( qwEndCount - qwStartCount )
/ (double) (signed __int64) QwUtilPerfCountFrq();
}
CHAR *GetDebugEnvValue( CHAR *szEnvVar );
ERR ErrUtilCloseHandle( HANDLE hf );
// for system information such as virtual page size and malloc granularity
extern SYSTEM_INFO siSystemConfig;
// Event Logging
typedef unsigned long MessageId;
#include "jetmsg.h"
extern int fNoWriteAssertEvent;
VOID UtilReportEvent( WORD fwEventType, WORD fwCategory, DWORD IDEvent, WORD cStrings, LPCTSTR *plpszStrings );
VOID UtilReportEventOfError( WORD fwCategory, DWORD IDEvent, ERR err );
// Registry Support
ERR ErrUtilRegInit(void);
ERR ErrUtilRegTerm(void);
ERR ErrUtilRegReadConfig(void);
extern HKEY hkeyHiveRoot;
ERR ErrUtilRegOpenKeyEx( HKEY hkeyRoot, LPCTSTR lpszSubKey, PHKEY phkResult );
ERR ErrUtilRegCloseKeyEx( HKEY hkey );
ERR ErrUtilRegCreateKeyEx( HKEY hkeyRoot,
LPCTSTR lpszSubKey,
PHKEY phkResult,
LPDWORD lpdwDisposition );
ERR ErrUtilRegDeleteKeyEx( HKEY hkeyRoot, LPCTSTR lpszSubKey );
ERR ErrUtilRegDeleteValueEx( HKEY hkey, LPTSTR lpszValue );
ERR ErrUtilRegSetValueEx( HKEY hkey,
LPCTSTR lpszValue,
DWORD fdwType,
CONST BYTE *lpbData,
DWORD cbData );
ERR ErrUtilRegQueryValueEx( HKEY hkey,
LPTSTR lpszValue,
LPDWORD lpdwType,
LPBYTE *lplpbData );
// DLL Support
STATIC INLINE BOOL FUtilLoadLibrary(const char *pszLibrary, ULONG_PTR *phmod)
{
HANDLE hmod;
hmod = LoadLibrary((LPTSTR) pszLibrary);
// restore original error mode
*phmod = (ULONG_PTR) hmod;
return(hmod != NULL);
}
STATIC INLINE PFN PfnUtilGetProcAddress(ULONG_PTR hmod, unsigned ordinal)
{
return((PFN) GetProcAddress((HANDLE) hmod, MAKEINTRESOURCE(ordinal)));
}
STATIC INLINE void UtilFreeLibrary( unsigned hmod ) { FreeLibrary( LongToHandle(hmod)); }
// Date and Time
void UtilGetDateTime(DATESERIAL *pdt);
void UtilGetDateTime2(_JET_DATETIME *pdt);
char *SzUtilSerialToDate(JET_DATESERIAL dt);
// File Operations
typedef OVERLAPPED OLP;
ERR ErrUtilCreateDirectory( char *szDirName );
ERR ErrUtilRemoveDirectory( char *szDirName );
ERR ErrUtilGetFileAttributes( CHAR *szFileName, BOOL *pfReadOnly );
ERR ErrUtilFindFirstFile( CHAR *szFind, HANDLE *phandleFind, CHAR *szFound );
ERR ErrUtilFindNextFile( HANDLE handleFind, CHAR *szFound );
VOID UtilFindClose( HANDLE handleFind );
BOOL FUtilFileExists( CHAR *szFilePathName );
ERR ErrUtilOpenFile( char *szFileName, HANDLE *phf, ULONG ulFileSize, BOOL fReadOnly, BOOL fOverlapped );
ERR ErrUtilOpenReadFile( char *szFileName, HANDLE *phf );
ERR ErrUtilDeleteFile( char *szFileName );
ERR ErrUtilNewSize( HANDLE hf, ULONG ulFileSize, ULONG ulFileSizeHigh, BOOL fOverlapped );
ERR ErrUtilMove( char *szFrom, char *szTo );
ERR ErrUtilCopy( char *szFrom, char *szTo, BOOL fFailIfExists );
ERR ErrUtilReadFile( HANDLE hf, VOID *pvBuf, UINT cbBuf, UINT *pcbRead );
ERR ErrUtilReadBlock( HANDLE hf, VOID *pvBuf, UINT cbBuf, UINT *pcbRead );
ERR ErrUtilReadBlockOverlapped( HANDLE hf, VOID *pvBuf, UINT cbBuf,
DWORD *pcbRead, OLP *polp );
ERR ErrUtilReadBlockEx( HANDLE hf, VOID *pvBuf, UINT cbBuf, OLP *polp, VOID *pfnCompletion);
ERR ErrUtilWriteBlock( HANDLE hf, VOID *pvBuf, UINT cbBuf, UINT *pcbWritten );
ERR ErrUtilWriteBlockOverlapped( HANDLE hf, VOID *pvBuf, UINT cbBuf,
DWORD *pcbWrite, OLP *polp );
ERR ErrUtilWriteBlockEx( HANDLE hf, VOID *pvBuf, UINT cbBuf, OLP *polp, VOID *pfnCompletion);
ERR ErrUtilGetOverlappedResult( HANDLE hf, OLP *polp, UINT *pcb,
BOOL fWait );
STATIC INLINE ERR ErrUtilCloseFile( HANDLE hf ) { return ErrUtilCloseHandle( hf ); }
ERR ErrUtilReadShadowedHeader( CHAR *szFileName, BYTE *pbHeader, INT cbHeader );
ERR ErrUtilWriteShadowedHeader( CHAR *szFileName, BYTE *pbHeader, INT cbHeader );
#define ulChecksumMagicNumber 0x89abcdef
ULONG UlUtilChecksum( const BYTE *pb, INT cb );
//+api------------------------------------------------------
//
// VOID UtilChgFilePtr( HANDLE hf, LONG lRel, LONG *plRelHigh, ULONG ulRef, ULONG *pul )
// =========================================================
//
// Changes file hf pointer to position lRef relative to position :
//
// wRef FILE_BEGIN file beginnging
//
//----------------------------------------------------------
STATIC INLINE VOID UtilChgFilePtr( HANDLE hf, LONG lRel, LONG *plRelHigh, ULONG ulRef, ULONG *pul )
{
Assert( sizeof(HANDLE) == sizeof(HFILE) );
*pul = SetFilePointer( (HANDLE)hf, lRel, plRelHigh, ulRef );
Assert( ulRef != FILE_BEGIN || *pul == (ULONG)lRel );
return;
}
STATIC INLINE ERR ErrUtilGetDiskFreeSpace( char *szRoot,
ULONG *pSecPerClust,
ULONG *pcbSec,
ULONG *pcFreeClust,
ULONG *pcTotClust )
{
if ( GetDiskFreeSpace( szRoot, pSecPerClust, pcbSec, pcFreeClust, pcTotClust ) )
return JET_errSuccess;
else
return ErrERRCheck( JET_errDiskIO );
}
VOID UtilDebugBreak();
// Physical Memory Allocation
#if defined( DEBUG ) || defined( RFS2 )
void *SAlloc( unsigned long );
void OSSFree( void * );
void *LAlloc( unsigned long, unsigned short );
void OSLFree( void * );
STATIC INLINE VOID SFree( void *pv ) { OSSFree( pv ); }
STATIC INLINE VOID LFree( void *pv ) { OSLFree( pv ); }
#else // !DEBUG && !RFS2
#include <stdlib.h>
STATIC INLINE VOID *SAlloc( ULONG cb ) { return GlobalAlloc( 0, cb ); }
STATIC INLINE VOID SFree( VOID *pv ) { GlobalFree( pv ); }
STATIC INLINE VOID *LAlloc( ULONG c, USHORT cb ) { return GlobalAlloc( 0, c * cb ); }
STATIC INLINE VOID LFree( VOID *pv ) { GlobalFree( pv ); }
#endif // DEBUG || RFS2
// Virtual Memory Allocation
#if defined( DEBUG ) || defined( RFS2 )
VOID *PvUtilAlloc( ULONG dwSize );
VOID *PvUtilCommit( VOID *pv, ULONG dwSize );
VOID UtilFree( VOID *pv );
VOID UtilDecommit( VOID *pv, ULONG dwSize );
#else // !DEBUG && !RFS2
STATIC INLINE VOID *PvUtilAlloc( ULONG dwSize )
{
return VirtualAlloc( NULL, dwSize, MEM_RESERVE, PAGE_READWRITE );
}
STATIC INLINE VOID *PvUtilCommit( VOID *pv, ULONG ulSize )
{
return VirtualAlloc( pv, ulSize, MEM_COMMIT, PAGE_READWRITE );
}
STATIC INLINE VOID UtilFree( VOID *pv ) { VirtualFree( pv, 0, MEM_RELEASE ); }
STATIC INLINE VOID UtilDecommit( VOID *pv, ULONG dwSize ) { VirtualFree( pv, dwSize, MEM_DECOMMIT ); }
#endif // DEBUG || RFS2
VOID *PvUtilAllocAndCommit( ULONG dwSize );
// Critical Sections
#ifdef SPIN_LOCK
void UtilEnterNestableCriticalSection(void *pv);
void UtilLeaveNestableCriticalSection(void *pv);
void UtilEnterCriticalSection(void *pv);
void UtilLeaveCriticalSection(void *pv);
ERR ErrUtilInitializeCriticalSection(void **ppv);
void UtilDeleteCriticalSection(void *pv);
#else // !SPIN_LOCK
#ifdef DEBUG
void UtilEnterNestableCriticalSection(void *pv);
void UtilLeaveNestableCriticalSection(void *pv);
void UtilEnterCriticalSection(void *pv);
void UtilLeaveCriticalSection(void *pv);
ERR ErrUtilInitializeCriticalSection(void **ppv);
void UtilDeleteCriticalSection(void *pv);
#else // !DEBUG
STATIC INLINE ERR ErrUtilInitializeCriticalSection(void **ppv)
{
if ( !( *ppv = SAlloc( sizeof( CRITICAL_SECTION ) ) ) )
return ErrERRCheck( JET_errOutOfMemory );
InitializeCriticalSection( (LPCRITICAL_SECTION) *ppv );
return JET_errSuccess;
}
STATIC INLINE VOID UtilDeleteCriticalSection(void *pv)
{
DeleteCriticalSection( (LPCRITICAL_SECTION) pv );
SFree( pv );
}
STATIC INLINE VOID UtilEnterCriticalSection(void *pv)
{
EnterCriticalSection( (LPCRITICAL_SECTION) pv );
}
STATIC INLINE VOID UtilLeaveCriticalSection(void *pv)
{
LeaveCriticalSection( (LPCRITICAL_SECTION) pv );
}
STATIC INLINE VOID UtilEnterNestableCriticalSection( void *pv ) { UtilEnterCriticalSection( pv ); }
STATIC INLINE VOID UtilLeaveNestableCriticalSection( void *pv ) { UtilLeaveCriticalSection( pv ); }
#endif // !DEBUG
#endif // !SPIN_LOCK
#ifdef RETAIL
#define UtilAssertCrit( pv ) 0
#define UtilAssertNotInCrit( pv ) 0
#define UtilHoldCriticalSection( pv ) 0
#define UtilReleaseCriticalSection( pv ) 0
#else // !RETAIL
void UtilAssertCrit(void *pv);
void UtilAssertNotInCrit(void *pv);
void UtilHoldCriticalSection(void *pv);
void UtilReleaseCriticalSection(void *pv);
#endif // !RETAIL
// Signals
typedef HANDLE SIG;
#define sigNil ( (SIG) 0 )
STATIC INLINE ERR ErrUtilSignalCreate( void **ppv, const char *szSig )
{
*((SIG *) ppv) = CreateEvent( NULL, fTrue, fFalse, szSig );
return ( *ppv == sigNil ) ? ErrERRCheck( JET_errOutOfMemory ) : JET_errSuccess;
}
STATIC INLINE ERR ErrUtilSignalCreateAutoReset( void **ppv, const char *szSig )
{
*((SIG *) ppv) = CreateEvent( NULL, fFalse, fFalse, szSig );
return ( *ppv == sigNil ) ? ErrERRCheck( JET_errOutOfMemory ) : JET_errSuccess;
}
STATIC INLINE void UtilSignalReset( void *pv )
{
BOOL rc;
rc = ResetEvent( (SIG) pv );
Assert( rc != FALSE );
}
STATIC INLINE void UtilSignalSend( void *pv )
{
BOOL rc;
rc = SetEvent( (SIG) pv );
Assert( rc != FALSE );
}
STATIC INLINE DWORD UtilSignalWait( void *pv, long lTimeOut )
{
DWORD rc;
UtilAssertNotInCrit( critJet );
rc = WaitForSingleObject( (SIG) pv, lTimeOut < 0 ? -1L : lTimeOut );
return rc;
}
STATIC INLINE DWORD UtilSignalWaitEx( void *pv, long lTimeOut, BOOL fAlertable )
{
DWORD rc;
UtilAssertNotInCrit( critJet );
rc = WaitForSingleObjectEx( (SIG) pv, lTimeOut < 0 ? -1L : lTimeOut, fAlertable );
return rc;
}
STATIC INLINE void UtilMultipleSignalWait( int csig, void *pv, BOOL fWaitAll, long lTimeOut )
{
DWORD rc;
UtilAssertNotInCrit( critJet );
rc = WaitForMultipleObjects( csig, (SIG*) pv, fWaitAll, lTimeOut < 0 ? -1L : lTimeOut );
}
void UtilCloseSignal(void *pv);
// Semaphore
typedef HANDLE SEM;
#define semNil ( (SEM) 0 )
STATIC INLINE ERR ErrUtilSemaphoreCreate( SEM *psem, LONG lInitialCount, LONG lMaximumCount )
{
*psem = ( SEM ) CreateSemaphore( NULL, lInitialCount, lMaximumCount, NULL );
return ( *psem == semNil ) ? ErrERRCheck( JET_errOutOfMemory ) : JET_errSuccess;
}
STATIC INLINE DWORD UtilSemaphoreWait( SEM sem, long lTimeOut )
{
DWORD rc;
rc = WaitForSingleObject( (HANDLE) sem, lTimeOut < 0 ? -1L : lTimeOut );
return rc;
}
STATIC INLINE DWORD UtilSemaphoreRelease( SEM sem, LONG cReleaseCount )
{
DWORD rc;
rc = ReleaseSemaphore( (HANDLE) sem, cReleaseCount, NULL );
Assert( rc != 0 );
return rc;
}
void UtilCloseSemaphore(void *pv);
// Threads and Processes
#define cmsecSleepMax (60*1000)
VOID UtilSleepEx( ULONG ulTime, BOOL fAlert );
VOID UtilSleep( ULONG ulTime );
ERR ErrUtilCreateThread( ULONG (*pulfn)(), ULONG cbStack, LONG lThreadPriority, HANDLE *phandle );
ULONG UtilEndThread( HANDLE hThread, SIG sigEnd );
#define lThreadPriorityNormal 0
#define lThreadPriorityHigh 1
void UtilSetThreadPriority( HANDLE hThread, LONG lThreadPriority );
STATIC INLINE HANDLE UtilGetCurrentTask( VOID ) { return LongToHandle(GetCurrentProcessId()); }
STATIC INLINE DWORD DwUtilGetCurrentThreadId( VOID ) { return GetCurrentThreadId(); }
// text normalization
ERR ErrUtilCheckLangid( LANGID *plangid );
VOID UtilNormText( char *rgchText, INT cchText, BYTE *rgchNorm, INT cbNorm, INT *pbNorm );
ERR ErrUtilNormText(
const BYTE *pbField,
INT cbField,
INT cbKeyBufLeft,
BYTE *pbSeg,
INT *pcbSeg );
#define BINARY_NAMES 1
#ifdef BINARY_NAMES
#define UtilCmpName( sz1, sz2 ) \
( _stricmp( sz1, sz2 ) )
#define UtilStringCompare( pb1, cb1, pb2, cb2, sort, plResult ) \
{ \
*plResult = strncmp( pb1, pb2, min( cb1, cb2 ) ); \
if ( !*plResult ) \
*plResult = cb1 > cb2; \
}
#else
INT UtilCmpName( const char *sz1, const char *sz2 );
VOID UtilStringCompare( char *pb1, unsigned long cb1,
char *pb2, unsigned long cb2, unsigned long sort,
long *plResult );
#endif
// Unicode Support
ERR ErrUtilMapString(LANGID langid, BYTE *pbField, INT cbField, BYTE *rgbSeg,
int cbBufLeft, int *cbSeg);
ERR ErrUtilWideCharToMultiByte(LPCWSTR lpcwStr, LPSTR *lplpOutStr);
// RFS functions
#ifdef RFS2
int UtilRFSAlloc( const char *szType, int Type );
int UtilRFSLog(const char *szType,int fPermitscritted);
void UtilRFSLogJETCall(const char *szFunc,ERR err,const char *szFile,unsigned Line);
void UtilRFSLogJETErr(ERR err,const char *szLabel,const char *szFile,unsigned szLine);
#endif /* RFS2 */
/*
** UtilInterlockedIncrement and UtilInterlockedDecrement are wrapper functions
** to increment or decrement a value in a thread-safe manner.
**
** Return values are:
**
** > 0 if resulting value > 0
** = 0 if resulting value = 0
** < 0 if resulting value < 0
**
** Note that the return value isn't necessary the resulting value; it may be
** different than the resulting value, but sign is guarenteed to be the same.
*/
STATIC INLINE long UtilInterlockedIncrement( long *lpValue )
{
return InterlockedIncrement( lpValue );
}
STATIC INLINE long UtilInterlockedDecrement( long *lpValue )
{
return InterlockedDecrement( lpValue );
}
/*
** UtilInterlockedExchange is a wrapper function to assign a value to a
** variable in a thread-safe manner.
**
** This function returns the prior value of the variable (before the
** assignment was done).
*/
STATIC INLINE long UtilInterlockedExchange( long *lpValue1, long lValue2 )
{
return InterlockedExchange( lpValue1, lValue2 );
}
// Debug output
#ifdef DEBUG
extern void * critDBGPrint;
VOID JET_API DBGFPrintF( char *sz );
void VARARG DebugWriteString(BOOL fHeader, const char *szFormat, ...);
#else
#define DBGFPrintF( sz ) 0
#endif
void UtilPerfDumpStats(char *szText);
// End Assert redirection
#undef szAssertFilename
#endif // _UTILW32_H