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.

148 lines
4.8 KiB

  1. #include <private.h>
  2. #include <errno.h>
  3. #include <strsafe.h>
  4. //
  5. // Invokes symchk.exe to validate symbols
  6. //
  7. BOOL CheckSymbols(LPSTR SourceFileName,
  8. LPSTR TmpPath,
  9. LPSTR ExcludeFileName,
  10. BOOL DbgControl,
  11. // ErrMsg is MAX_SYM_ERR * sizeof(CHAR) in length
  12. LPSTR ErrMsg,
  13. size_t ErrMsgLen) {
  14. BOOL bReturn = TRUE;
  15. DWORD dwReturn;
  16. FILE *pfErrors;
  17. INT iReturn;
  18. TCHAR szBuf[ MAX_PATH*4 ];
  19. TCHAR szTempPath[MAX_PATH+1];
  20. TCHAR szTempFileName[MAX_PATH+1];
  21. TCHAR *pChar;
  22. UINT uiReturn;
  23. //
  24. // Find the temp dir
  25. //
  26. dwReturn = GetTempPath(MAX_PATH+1, szTempPath);
  27. if (dwReturn == 0) {
  28. // GetTempPath failed, just use the current directory.
  29. StringCbCopy(szTempPath,sizeof(szTempPath),".");
  30. }
  31. //
  32. // Get a temp file to pipe output to
  33. //
  34. uiReturn= GetTempFileName(szTempPath, "BNP", 0, szTempFileName);
  35. if (uiReturn == 0) {
  36. StringCbCopy(ErrMsg, ErrMsgLen, "Unable to get temporary file name");
  37. return(FALSE);
  38. }
  39. //
  40. // Build the command line
  41. //
  42. StringCbPrintfA(szBuf,
  43. sizeof(szBuf),
  44. "symchk.exe %s /s %s /f ",
  45. SourceFileName,
  46. TmpPath);
  47. // Optional flags
  48. if ( DbgControl ) {
  49. StringCbCat( szBuf, sizeof(szBuf), " /t");
  50. }
  51. if ( ExcludeFileName != NULL ) {
  52. StringCbCat( szBuf, sizeof(szBuf), " /e ");
  53. StringCbCat( szBuf, sizeof(szBuf), ExcludeFileName );
  54. }
  55. // Redirect the output to a file
  56. StringCbCat( szBuf, sizeof(szBuf), " > ");
  57. StringCbCat( szBuf, sizeof(szBuf), szTempFileName);
  58. // From Oct 2001 MSDN:
  59. // You must explicitly flush (using fflush or _flushall) or close any stream before calling system
  60. // It doesn't specify if stdin, stderr, and stdout are included here, so call it just to
  61. // be safe.
  62. _flushall();
  63. //
  64. // Spawn off symchk.exe - this is a security risk since we don't specifically specify the path
  65. // to symchk.exe. However, we can't guarentee that it exists nor that
  66. // if we find it dynamically that the correct one will be used so I'm not
  67. // certain that we can do this any differently.
  68. //
  69. iReturn = system(szBuf);
  70. // Check for Error line in the output file
  71. if (iReturn != 0) {
  72. bReturn = FALSE;
  73. // symchk error return value
  74. if (iReturn == 1) {
  75. // open the error file
  76. pfErrors = fopen(szTempFileName, "r");
  77. // if the file couldn't be opened
  78. if (pfErrors == NULL) {
  79. StringCbCopy(ErrMsg, ErrMsgLen, "Can't open symchk error file");
  80. // parse the error file
  81. } else {
  82. if ( fgets( ErrMsg, ErrMsgLen, pfErrors ) == NULL) {
  83. if ( feof(pfErrors) || ferror(pfErrors) ) {
  84. StringCbCopy(ErrMsg, ErrMsgLen, "Can't read symchk error file");
  85. } else {
  86. StringCbCopy(ErrMsg, ErrMsgLen, "Unexpected error");
  87. }
  88. } else if ( (pChar = strchr(ErrMsg,'\n')) != NULL ) {
  89. // remove \n
  90. pChar = '\0';
  91. // message is too short to be meaningful
  92. if (strlen(ErrMsg) <= 8) {
  93. StringCbCopy(ErrMsg, ErrMsgLen, "Unknown Error");
  94. }
  95. }
  96. fclose(pfErrors);
  97. }
  98. // system defined errors
  99. } else if (errno == E2BIG ||
  100. errno == ENOENT ||
  101. errno == ENOMEM) {
  102. pChar = strerror(errno);
  103. StringCbCopy(ErrMsg, ErrMsgLen, pChar);
  104. // system defined errors intentionally ignored
  105. } else if (errno == ENOEXEC) {
  106. // If we return FALSE, binplace is going to start returning up the call stack, so just print
  107. // our own error message and pretend everything is fine by returning TRUE.
  108. fprintf(stderr,"BINPLACE : error BNP2404: Unable to call symchk.exe, not checking symbols.\n");
  109. bReturn = TRUE;
  110. // unknown error
  111. } else {
  112. StringCbPrintfA(ErrMsg, ErrMsgLen, "Unexpected error. SymChk returned 0x%x.",iReturn);
  113. }
  114. }
  115. // cleanup the temp file and return
  116. if ( DeleteFile(szTempFileName) == 0 ) {
  117. fprintf(stderr,"BINPLACE : warning BNP2440: Unable to delete temp file \"%s\". Error 0x%x\n.",
  118. szTempFileName, GetLastError());
  119. }
  120. return(bReturn);
  121. }