home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / odbc / admndemo / standard.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-06  |  10.7 KB  |  342 lines

  1. //*---------------------------------------------------------------------------------
  2. //|  ODBC System Administrator
  3. //|
  4. //|  This code is furnished on an as-is basis as part of the ODBC SDK and is
  5. //|  intended for example purposes only.
  6. //|
  7. //|   Title:   STANDARD.C
  8. //|      This module contains standard functions which can be used by many
  9. //|      different tools.
  10. //|
  11. //|      The DumpDebugInfo function when enabled will cause all memory requests
  12. //|      and frees to be written to a comma separated file.  This file can then
  13. //|      be queries via the sample Text ODBC Driver to find memory problems.
  14. //*---------------------------------------------------------------------------------
  15. #include "standard.h"
  16. #include <windowsx.h>
  17. #include <string.h>
  18. #include <stdlib.h>
  19. #include <stdio.h>
  20. #include <stdarg.h>
  21. #include "errcheck.h"
  22. #include "strings.h"
  23.  
  24.  
  25.  
  26. //*---------------------------------------------------------------------------------
  27. //|   Global variables
  28. //*---------------------------------------------------------------------------------
  29. char OutStr[MAXBUFF];
  30. dCSEG(char) szui[]                        =  "%u";
  31. dCSEG(char) szEmpty[]                     =  "\0";
  32. dCSEG(char) szcrlf[]                      =  "\r\n";
  33.  
  34. #ifdef _DEBUG
  35. #include "time.h"
  36. #define szASSERTERROR (LPSTR)"Assert: %s, %s, %d"
  37. #define szDEBUGFILE (LPSTR)"C:\\TMP\\MEM"
  38. char szDbgOut[200];
  39. BOOL fNew=TRUE;
  40.  
  41. void WinAssertReal(int exp, LPSTR msg, LPSTR file, int line)
  42. {
  43.    if(!exp) {
  44.       wsprintf(szDbgOut, szASSERTERROR, msg, file, line);
  45.       MessageBox(GetActiveWindow(), szDbgOut, szErrTitle, MB_OK);
  46.    }
  47. }
  48.  
  49. void DumpDebugInfo(LPVOID tmp, LPSTR szFile, int cbLine, int stat,
  50.          DWORD rqSize, DWORD aSize)
  51. {
  52.    static   OFSTRUCT    ofs;
  53.    static   HFILE       hf;
  54.    static   time_t      thetime;
  55.    static   struct tm * tmVal;
  56.  
  57.    if(fNew) {
  58.       fNew = FALSE;
  59.       ofs.cBytes = sizeof(OFSTRUCT);
  60.       hf = OpenFile(szDEBUGFILE, &ofs, OF_DELETE);
  61.       _lclose(hf);
  62.    }
  63.  
  64.    // Creates file MEM which is a comma separated text file.
  65.    // Issue the select statement to find memory ptrs
  66.    // which were allocated but never freed (status=1), and
  67.    // pointers which were freed but never allocated (status=-1).
  68.    // Of course "No data found" is the desired response.
  69.    //    create table mem
  70.    //        (address char(9),
  71.    //         logtime char(8),
  72.    //         status integer,
  73.    //         desired integer,
  74.    //         actual integer,
  75.    //         line integer,
  76.    //         file char(45))
  77.    //    select address, sum(status) from mem
  78.    //      group by address having sum(status) <> 0
  79.    time(&thetime);
  80.    tmVal = localtime(&thetime);
  81.    wsprintf(szDbgOut, (LPSTR)"%04X:%04X,%02u:%02u:%02u,%d,%lu,%lu,%u,%s\r\n",
  82.             HIWORD(tmp), LOWORD(tmp), tmVal->tm_hour, tmVal->tm_min, tmVal->tm_sec,
  83.             stat, rqSize, aSize, cbLine, (LPSTR)szFile);
  84.    if((hf = _lopen(szDEBUGFILE, WRITE)) == -1)  // File not found
  85.       hf = OpenFile(szDEBUGFILE, &ofs, OF_CREATE);
  86.    _llseek(hf, 0L, 2);                    // Try to go to end of file
  87.    _lwrite(hf, szDbgOut, lstrlen(szDbgOut));  // Write wherever we are
  88.    _lclose(hf);
  89. }
  90.  
  91. void FAR * DebugGetMemory(DWORD size, LPSTR szFile, int cbLine)
  92. {
  93.    LPVOID   ptr;
  94.    DWORD    aSize;
  95.  
  96.    ptr = DoGetMemory(size);
  97.    if(!ptr)
  98.       return ptr;
  99.    aSize = GlobalSize(GlobalPtrHandle(ptr));
  100.    DumpDebugInfo(ptr, szFile, cbLine, 1, size, aSize);
  101.  
  102.    return ptr;
  103. }
  104.  
  105. void DebugReleaseMemory(LPVOID ptr, LPSTR szFile, int cbLine)
  106. {
  107.    GlobalFreePtr(ptr);
  108.    DumpDebugInfo(ptr, szFile, cbLine, -1, 0, 0);
  109. }
  110. #endif      // Debug memory routines
  111.  
  112.  
  113. //*---------------------------------------------------------------------------------
  114. //| DoGetMemory:
  115. //|   This function allocates the specified amount of memory.
  116. //| Parms:
  117. //|   in       size                 How much memory
  118. //| Returns:
  119. //|   Long pointer to void
  120. //*---------------------------------------------------------------------------------
  121. void FAR * DoGetMemory(DWORD size)
  122. {
  123.    LPVOID   tmp;
  124.  
  125.    tmp = GlobalAllocPtr(GMEM_FIXED | GMEM_ZEROINIT, size);
  126.    if(!tmp)
  127.       szMessageBox(GetActiveWindow(),
  128.                    MB_ICONEXCLAMATION,
  129.                    (LPSTR)szErrTitle,
  130.                    GetidsString(idsOutOfMemory, OutStr, MAXBUFF));
  131.    return tmp;
  132. }
  133.  
  134.  
  135. //*---------------------------------------------------------------------------------
  136. //| DoReleaseMemory:
  137. //|   Free up the memory we have requested
  138. //| Parms:
  139. //|   ptr         The pointer to free
  140. //| Returns:
  141. //|   Nothing.
  142. //*---------------------------------------------------------------------------------
  143. void DoReleaseMemory(LPVOID ptr)
  144. {
  145.    GlobalFreePtr(ptr);
  146. }
  147.  
  148.  
  149. //*---------------------------------------------------------------------------------
  150. //| RemoveCrLf:
  151. //|   This will remove all carriage return/line feeds from the input buffer.
  152. //| Parms:
  153. //|   in       instr                Null terminated string
  154. //| Returns:
  155. //|   Nothing
  156. //*---------------------------------------------------------------------------------
  157. void RemoveCrLf(LPSTR instr)
  158. {
  159.    LPSTR str=instr;
  160.  
  161.    if(!str ||
  162.       !*str)
  163.       return;
  164.    while((str = _fstrstr(str, (LPSTR)szcrlf))) {
  165.       *str++ = ' ';
  166.       *str++ = ' ';
  167.    }
  168. }
  169.  
  170.  
  171. //*---------------------------------------------------------------------------------
  172. //| GetNewDirectory:
  173. //|   This function will take a complete file name (must have path included)
  174. //|   and return only the path portion with no trailing '\'
  175. //| Parms:
  176. //|   outstr            Output path name with no file
  177. //|   instr             Input complete file name
  178. //| Returns:
  179. //|   Nothing
  180. //*---------------------------------------------------------------------------------
  181. void GetNewDirectory(LPSTR outstr, LPSTR instr)
  182. {
  183.    LPSTR    str=outstr;
  184.    LPSTR    lstr=outstr;
  185.  
  186.    lstrcpy(str, instr);
  187.    while((str = _fstrchr(lstr+1, '\\')))
  188.       lstr = str++;
  189.    *++lstr = '\0';
  190. }
  191.  
  192.  
  193. //*---------------------------------------------------------------------------------
  194. //| ValidName:
  195. //|   This function parses a string to look for invalid characters which would
  196. //|   preclude it from being written as a section or entry in an .ini file.
  197. //| Parms:
  198. //|   instr             Input complete file name
  199. //| Returns:
  200. //|   TRUE if it is valid, FALSE on error
  201. //*---------------------------------------------------------------------------------
  202. BOOL ValidName(LPSTR instr)
  203. {
  204.    LPSTR str=instr;
  205.    if(!str)
  206.       return TRUE;
  207.    while(*str)
  208.       switch(*str) {
  209.         case '[':
  210.         case ']':
  211.         case '=':
  212.          return FALSE;
  213.  
  214.         default:
  215.          ++str;
  216.       }
  217.    return TRUE;
  218. }
  219.  
  220.  
  221. //*---------------------------------------------------------------------------------
  222. //| lpatoi:
  223. //|   atoi only works for NEAR host vars, which makes it useless in a large
  224. //|   application.  This function tricks atoi by copy the long string to a
  225. //|   local variable and then doing the conversion.  This is a major cluge,
  226. //|   but a necessary one.
  227. //| Parms:
  228. //|   instr             Input number
  229. //| Returns:
  230. //|   The integer value of instr
  231. //*---------------------------------------------------------------------------------
  232. int lpatoi(LPSTR instr)
  233. {
  234.    char szStr[35];
  235.    lstrcpy((LPSTR)szStr, instr);
  236.    return atoi(szStr);
  237. }
  238.  
  239.  
  240. //*------------------------------------------------------------------------
  241. //|  GetidsString:
  242. //|      Will retrieve a string from our resource fork given the id.
  243. //|  Parms:
  244. //|      ids            The id of the string
  245. //|      szOut          Output buffer for string
  246. //|      cbSize         How big is the buffer
  247. //|  Returns:
  248. //|      Pointer to szOut
  249. //*------------------------------------------------------------------------
  250. LPSTR EXTFUN GetidsString(UINT ids, LPSTR szOut, UINT cbSize)
  251. {
  252.    extern HINSTANCE hInst;
  253.  
  254.    if(!szOut)
  255.       return NULL;
  256.    if(!LoadString(hInst, ids, szOut, cbSize))
  257.       lstrcpy(szOut, "Not found");
  258.    return szOut;
  259. }
  260.  
  261.  
  262.  
  263. //*------------------------------------------------------------------------
  264. //|  szWrite:
  265. //|      Allows you to format an output string which is then added
  266. //|      to the specified edit window.
  267. //|  Parms:
  268. //|      hwnd           Edit window for output
  269. //|      szFmt          Format string
  270. //|      (varying)      Arguements for format string
  271. //|  Returns:
  272. //|      Nothing
  273. //*------------------------------------------------------------------------
  274. VOID FAR CDECL szWrite(HWND hwnd, LPSTR szFmt, ...)
  275. {
  276. #define MAXEDITBUFF 30000
  277.    static      char  szBuffer[MAXBUFF];
  278.    UCHAR *     pszBuffer;
  279.    UCHAR       bufFmt[MAXBUFF];
  280.    va_list           marker;
  281.    UINT              rtn=0;
  282.    UINT              len=0;
  283.  
  284.  
  285.    pszBuffer = &szBuffer[0];
  286.    lstrcpy(bufFmt, szFmt);
  287.  
  288.    // Use format and arguements as input
  289.    va_start(marker, szFmt);
  290.    if (_vsnprintf(pszBuffer, MAXBUFF, bufFmt, marker) < 0) {
  291.       wsprintf(pszBuffer,"Buffer overflow reporting '%*.*s'", 50,50,(LPSTR)szBuffer);
  292.       return;
  293.    }
  294.    va_end(marker);
  295.  
  296.  
  297.    // Now we have the string to add to the end of our output.  Verify that the
  298.    // new string will not be too large and set selection accordingly.
  299.    len = (UINT)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0L);
  300.    if(len + lstrlen(pszBuffer) > MAXEDITBUFF) {    //  Need to truncate
  301.       SendMessage(hwnd, EM_SETSEL, 0, MAKELPARAM(0,len + 10));
  302.       SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM)((LPSTR)"...\r\n"));
  303.       SendMessage(hwnd, EM_SETSEL, 0, MAKELPARAM(len,len));
  304.    }
  305.    SendMessage(hwnd, EM_REPLACESEL, 0, (LPARAM)((LPSTR)pszBuffer));
  306. }
  307.  
  308.  
  309. //*------------------------------------------------------------------------
  310. //|  szMessageBox:
  311. //|      Works like sprintf only the output goes to a message box.
  312. //|  Parms:
  313. //|      hwnd           Owner window, NULL uses GetActiveWindow
  314. //|      style          Flags for MessageBox
  315. //|      szTitle        Title for message box
  316. //|      szFmt          Format string
  317. //|      (varying)      Arguements for format string
  318. //|  Returns:
  319. //|      Id from MessageBox
  320. //*------------------------------------------------------------------------
  321. int FAR CDECL szMessageBox(HWND hwnd, UINT style, LPSTR szTitle, LPSTR szFmt, ...)
  322. {
  323.    char        szBuffer[MAXBUFF];
  324.    char *      pszBuffer;
  325.    UCHAR       bufFmt[MAXBUFF];
  326.    va_list     marker;
  327.  
  328.    pszBuffer = &szBuffer[0];
  329.    lstrcpy(bufFmt, szFmt);
  330.  
  331.    // Use format and arguements as input
  332.    va_start(marker, szFmt);
  333.    if (_vsnprintf(pszBuffer, MAXBUFF, bufFmt, marker) < 0)
  334.       wsprintf(pszBuffer,"Buffer overflow reporting '%*.*s'", 50,50,szBuffer);
  335.    va_end(marker);
  336.  
  337.    return(MessageBox((hwnd) ? hwnd : GetActiveWindow(),
  338.                      pszBuffer,
  339.                      szTitle,
  340.                      style) == IDOK);
  341. }
  342.