/*================================================================================ $ Copyright (C) 1997 Microsoft Corporation File: gmacros.h Contains: Macros used in common by both the DHCP Server and the DHCP Client. Most of them are inlines for sake of elegance and ease of usage. Author: RameshV Created: 04-Jun-97 00:01 ================================================================================*/ #include // Some block macros; usage at end // Disable the warning about unreference labels. #pragma warning(disable : 4102) #define _shorten(string) ( strrchr(string, '\\')? strrchr(string, '\\') : (string) ) // print a message and the file and line # of whoever is printing this. #define _TracePrintLine(Msg) DhcpPrint((DEBUG_TRACE_CALLS, "%s:%d %s\n", _shorten(__FILE__), __LINE__, Msg)) #define BlockBegin(Name) { BlockStart_ ## Name : _TracePrintLine( "Block -> " #Name ); #define BlockEnd(Name) BlockEnd_ ## Name : _TracePrintLine( "Block <- " #Name ) ;} #define BlockContinue(Name) do { _TracePrintLine( "Continue to " #Name); goto BlockStart_ ## Name; } while (0) #define BlockBreak(Name) do { _TracePrintLine( "Breaking out of " #Name); goto BlockEnd_ ## Name; } while (0) #define RetFunc(F,Ret) do {_TracePrintLine( "Quitting function " #F ); return Ret ; } while (0) // The way to use the above set of simple block macros is as follows: (example usage) #if 0 int DummyFunction(VOID) { BlockBegin(DummyFunctionMain) { if(GlobalCount > 0 ) BlockContinue(DummyFunctionMain); else GlobalCount ++; if(GlobalCount > GlobalCountMax) BlockBreak(DummyFunctionMain); } BlockEnd(DummyFunctionMain); RetFunc(DummyFunction, RetVal); } #endif // now come some little more complicated functions.. // note that these can be freely mixed with the above set of simple functions. #define BlockBeginEx(Name, String) {BlockStart_ ## Name : _TracePrintLine( #String ); #define BlockEndEx(Name, String) BlockEnd_## Name : _TracePrintLine( #String );} #define BlockContinueEx(Name, String) do {_TracePrintLine( #String); goto BlockStart_ ## Name; } while (0) #define BlockBreakEx(Name, String) do {_TracePrintLine( #String); goto BlockEnd_ ## Name; } while(0) #define RetFuncEx(Name,Ret,DebMsg) do {_TracePrintLine( "QuittingFunction " #Name); DhcpPrint(DebMsg); return Ret;} while(0) // usage example: #if 0 int DummyFunction(VOID) { BlockBeginEx(Main, "Entering Dummy Function" ) { if( GlobalCount > 0) BlockContinueEx(Main, GlobalCount > 0); else GlobalCount ++; if(GlobalCount > GlobalCountMax) BlockBreak(Main); } BlockEndEx(Main, "Done Dummy Function"); RetFunc(DummyFunc, RetVal); // OR RetFuncEx(DummyFunc, RetVal, (DEBUG_ERRROS, "Function returning, gcount = %ld\n", GlobalCount)); } #endif 0 #define NOTHING // Now if a VOID function (procedure) returns, we can say RetFunc(VoidFunc, NOTHING) and things will work. //================================================================================ // Now some useful inlines. //================================================================================ VOID _inline FreeEx(LPVOID Ptr) { if(Ptr) DhcpFreeMemory(Ptr); } VOID _inline FreeEx2(LPVOID Ptr1, LPVOID Ptr2) { FreeEx(Ptr1); FreeEx(Ptr2); } VOID _inline FreeEx3(LPVOID Ptr1, LPVOID Ptr2, LPVOID Ptr3) { FreeEx(Ptr1); FreeEx(Ptr2); FreeEx(Ptr3); } VOID _inline FreeEx4(LPVOID Ptr1, LPVOID Ptr2, LPVOID Ptr3, LPVOID Ptr4) { FreeEx2(Ptr1, Ptr2); FreeEx2(Ptr3, Ptr4); } //-------------------------------------------------------------------------------- // All the alloc functions below, allocate in one shot a few pointers, // and initialize them.. aligning them correctly. //-------------------------------------------------------------------------------- LPVOID _inline AllocEx(LPVOID *Ptr1, DWORD Size1, LPVOID *Ptr2, DWORD Size2) { DWORD Size = ROUND_UP_COUNT(Size1, ALIGN_WORST) + Size2; LPBYTE Ptr = DhcpAllocateMemory(Size); if(!Ptr) return NULL; (*Ptr1) = Ptr; (*Ptr2) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST); return Ptr; } LPVOID _inline AllocEx2(LPVOID *Ptr1, DWORD Size1, LPVOID *Ptr2, DWORD Size2) { DWORD Size = ROUND_UP_COUNT(Size1, ALIGN_WORST) + Size2; LPBYTE Ptr = DhcpAllocateMemory(Size); if(!Ptr) return NULL; (*Ptr1) = Ptr; (*Ptr2) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST); return Ptr; } LPVOID _inline AllocEx3(LPVOID *Ptr1, DWORD Size1, LPVOID *Ptr2, DWORD Size2, LPVOID *Ptr3, DWORD Size3) { DWORD Size = ROUND_UP_COUNT(Size1, ALIGN_WORST) + ROUND_UP_COUNT(Size2, ALIGN_WORST) + Size3; LPBYTE Ptr = DhcpAllocateMemory(Size); if(!Ptr) return NULL; (*Ptr1) = Ptr; (*Ptr2) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST); (*Ptr3) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST) + ROUND_UP_COUNT(Size2, ALIGN_WORST); return Ptr; } LPVOID _inline AllocEx4(LPVOID *Ptr1, DWORD Size1, LPVOID *Ptr2, DWORD Size2, LPVOID *Ptr3, DWORD Size3, LPVOID *Ptr4, DWORD Size4) { DWORD Size = ROUND_UP_COUNT(Size1, ALIGN_WORST) + ROUND_UP_COUNT(Size2, ALIGN_WORST) + ROUND_UP_COUNT(Size3, ALIGN_WORST) + Size4; LPBYTE Ptr = DhcpAllocateMemory(Size); if(!Ptr) return NULL; (*Ptr1) = Ptr; (*Ptr2) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST); (*Ptr3) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST) + ROUND_UP_COUNT(Size2, ALIGN_WORST); (*Ptr4) = Ptr + ROUND_UP_COUNT(Size1, ALIGN_WORST) + ROUND_UP_COUNT(Size2, ALIGN_WORST) + ROUND_UP_COUNT(Size3, ALIGN_WORST); return Ptr; } //-------------------------------------------------------------------------------- // This function takes an input string and a static buffer and if the input // string is not nul terminated, copies it to the static buffer and then null // terminates it. It also change the size to reflect the new size.. //-------------------------------------------------------------------------------- LPBYTE _inline AsciiNulTerminate(LPBYTE Input, DWORD *Size, LPBYTE StaticBuf, DWORD BufSize) { if( 0 == *Size) return Input; // nothing to copy if(!Input[(*Size)-1]) return Input; // Everything is fine. if(*Size >= BufSize) { // Nothing much can be done here.. this is an error.. insufficient buffer space. DhcpAssert(FALSE); *Size = BufSize - 1; } memcpy(StaticBuf, Input, (*Size)); StaticBuf[*Size] = '\0'; (*Size) ++; return StaticBuf; } #if DBG #define INLINE #else #define INLINE _inline #endif #define BEGIN_EXPORT #define END_EXPORT #define AssertReturn(Condition, RetVal ) do { DhcpAssert(Condition); return RetVal ;} while(0) //================================================================================ // End of File. //================================================================================