home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Internet Business Development Kit / PRODUCT_CD.iso / sqlsvr / odbcsdk / samples / admndemo / standard.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-07  |  9.9 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));
  341. }
  342.