Source code of Windows XP (NT5)
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.

436 lines
14 KiB

  1. #include <windows.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <process.h>
  5. #include <tchar.h>
  6. #include <ctype.h>
  7. #include <spdebug.h>
  8. #include <sphelper.h>
  9. #define TEST (0)
  10. #define HEADERSRC "\\\\b11nlbuilds\\sapi5\\"
  11. #define BUILDDEST "\\\\b11nlbuilds\\sapi5\\"
  12. #if TEST
  13. #define TESTDEST "c:\\"
  14. #else
  15. #define TESTDEST "\\\\b11nlbuilds\\sapi5\\"
  16. #endif
  17. const int c_NoLog = -202;
  18. const int c_Toast = -201;
  19. struct FILETOCOPY
  20. {
  21. char * szRelativePath;
  22. char * szDescription;
  23. char * szColor;
  24. };
  25. FILETOCOPY g_aSAPIfiles[] =
  26. {
  27. {"release\\msi\\x86\\setup.exe", "Install SDK", "#00fefe"},
  28. {"release\\msm\\x86", "Retail Merge Module drop directory", "#00fefe"},
  29. {"debug\\msi\\x86\\setup.exe", "Install SDK", "#aaaaaa"},
  30. {"debug\\msm\\x86", "Debug Merge Module drop directory", "#aaaaaa"},
  31. };
  32. FILETOCOPY g_aSRfiles[] =
  33. {
  34. // {"release\\cab\\x86\\mscsr5.EXE", "SAPI5", "#aaaaaa"},
  35. // {"debug\\cab\\x86\\mscsr5.EXE", "SAPI5", "#ffff00"},
  36. {"srd1033.EXE", "English", "#aaaaaa"},
  37. {"srd1041.EXE", "Japanese", "#aaaaaa"},
  38. };
  39. #define DIM(a) (sizeof(a)/sizeof(a[0]))
  40. int ParseBVTLogfile( CHAR* pszBuildNumber, CHAR* pszFileName , DWORD* pcTotal);
  41. void PrintToFile(HANDLE hFile, char * szFormat, ...)
  42. {
  43. DWORD dw;
  44. char buf[2048];
  45. va_list vl;
  46. va_start(vl, szFormat);
  47. int i = _vsnprintf(buf, 2048, szFormat, vl);
  48. va_end(vl);
  49. WriteFile(hFile, buf, i, &dw, NULL);
  50. }
  51. char * GetFileText(char * szFileName, DWORD * pdwSize)
  52. {
  53. HANDLE hFile;
  54. CHAR * pbuff = NULL;
  55. DWORD dwSize;
  56. hFile = CreateFile( szFileName, GENERIC_READ,
  57. FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY, NULL );
  58. if( hFile == INVALID_HANDLE_VALUE )
  59. return NULL;
  60. dwSize = GetFileSize( hFile, NULL );
  61. if( dwSize == 0xffffffff )
  62. return NULL;
  63. pbuff = new CHAR [dwSize];
  64. if (pbuff)
  65. ReadFile( hFile, pbuff, dwSize, &dwSize, NULL );
  66. CloseHandle( hFile );
  67. if(pdwSize) *pdwSize = dwSize;
  68. return pbuff;
  69. }
  70. void cryAndDie(char* szError, unsigned short errCode)
  71. {
  72. printf("Fatal : %s\n", szError);
  73. printf("Exiting ...\n");
  74. exit(errCode);
  75. }
  76. int main(void)
  77. {
  78. HANDLE hFile, hFileSR, hExistingFile, hDir;
  79. CHAR *pbuff = NULL, szRoot[MAX_PATH], *pdirs, delBuff[MAX_PATH];
  80. DWORD dwSize, i, dw;
  81. BY_HANDLE_FILE_INFORMATION FileInfo;
  82. SYSTEMTIME SystemTime;
  83. FILETIME FileTime;
  84. // First create the SAPI file.
  85. // open file that contains the html template
  86. pbuff = GetFileText(HEADERSRC "Web.Files\\header.html", &dwSize);
  87. if( pbuff == NULL )
  88. {
  89. cryAndDie("Could not open Web.Files\\header.html", 1);
  90. }
  91. // Open the output file, write the header
  92. hFile = CreateFile( TESTDEST "Web.Files\\x86build.html",
  93. GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
  94. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  95. if( hFile != INVALID_HANDLE_VALUE )
  96. {
  97. WriteFile( hFile, pbuff, dwSize, &dw, NULL );
  98. }
  99. else
  100. {
  101. LPVOID lpMsgBuf;
  102. FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
  103. FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),
  104. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  105. (LPTSTR) &lpMsgBuf, 0, NULL );
  106. // Process any inserts in lpMsgBuf.
  107. // ...
  108. // Display the string.
  109. printf("ERROR: ");
  110. printf((LPTSTR) lpMsgBuf);
  111. printf("\n");
  112. // Free the buffer.
  113. LocalFree( lpMsgBuf );
  114. sprintf((LPTSTR) &lpMsgBuf,"Could not open %sWeb.Files\\x86build.html", TESTDEST);
  115. cryAndDie((LPTSTR)&lpMsgBuf, 1);
  116. }
  117. delete pbuff;
  118. // Now generate the SR file
  119. // open file that contains the html template
  120. pbuff = GetFileText(HEADERSRC "Web.Files\\SRheader.html", &dwSize);
  121. if( pbuff == NULL )
  122. {
  123. cryAndDie("Could not open Web.Files\\SRheader.html", 1);
  124. }
  125. // Write the header
  126. hFileSR = CreateFile( TESTDEST "Web.Files\\x86SRbld.html",
  127. GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
  128. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  129. if( hFileSR != INVALID_HANDLE_VALUE )
  130. {
  131. WriteFile( hFileSR, pbuff, dwSize, &dw, NULL );
  132. }
  133. else
  134. {
  135. cryAndDie("Could create file Web.Files\\x86SRbld.html", 1);
  136. }
  137. // Set registry key to ignore asserts for BVT testing (if necessary of course)
  138. DWORD dwFlags;
  139. DWORD dwSizeRet = sizeof(dwFlags);
  140. HKEY hkResult;
  141. if( RegOpenKeyEx( HKEY_CLASSES_ROOT, _T("SPDebugFlags"), 0,
  142. KEY_READ | KEY_SET_VALUE, &hkResult ) == ERROR_SUCCESS )
  143. {
  144. if( RegQueryValueEx( hkResult, _T("Flags"), NULL, NULL,
  145. (PBYTE)&dwFlags, &dwSizeRet ) == ERROR_SUCCESS )
  146. {
  147. if( !(dwFlags & SPDBG_NOASSERTS) )
  148. {
  149. dwFlags |= SPDBG_NOASSERTS;
  150. RegSetValueEx( hkResult, _T("Flags"), NULL, REG_DWORD, (PBYTE)&dwFlags, sizeof(dwFlags) );
  151. }
  152. }
  153. RegCloseKey( hkResult );
  154. }
  155. // Get a list of the currently-available builds.
  156. system( "dir /b /o-n " BUILDDEST "*. > dirs.txt" );
  157. pdirs = GetFileText("dirs.txt", &dwSize);
  158. if( pdirs==NULL )
  159. {
  160. cryAndDie("Could not open dirs.txt", 1);
  161. }
  162. CHAR *pTmp, *pEnd = pdirs + dwSize;
  163. int count = 0;
  164. strcpy( szRoot, BUILDDEST );
  165. int cchRoot = strlen(szRoot);
  166. // For each build...
  167. do
  168. {
  169. pTmp = szRoot + cchRoot;
  170. while( *pdirs != 13 )
  171. {
  172. *pTmp++ = *pdirs++;
  173. }
  174. *pTmp = 0;
  175. pdirs += 2;
  176. // Make sure there are no more than 10 builds in this directory.
  177. if( (++count > 10) && isdigit(szRoot[cchRoot]) )
  178. {
  179. i = sprintf( delBuff, "del /F /Q %s", szRoot );
  180. delBuff[i] = '\0';
  181. system( delBuff );
  182. continue;
  183. }
  184. hDir = CreateFile( szRoot, GENERIC_READ, FILE_SHARE_READ, NULL,
  185. OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
  186. if( hDir != INVALID_HANDLE_VALUE )
  187. {
  188. if( GetFileInformationByHandle( hDir, &FileInfo ) )
  189. {
  190. // Write date
  191. if( FileTimeToLocalFileTime( &FileInfo.ftCreationTime, &FileTime ) )
  192. {
  193. if( FileTimeToSystemTime( &FileTime, &SystemTime ) )
  194. {
  195. PrintToFile( hFile, "<TR>\x0d\x0a <TD ><FONT FACE=Arial ><B>%02d/%02d/%02d</B>\x0d\x0a", SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear % 100 );
  196. PrintToFile( hFileSR, "<TR>\x0d\x0a <TD ><FONT FACE=Arial ><B>%02d/%02d/%02d</B>\x0d\x0a", SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear % 100 );
  197. }
  198. }
  199. }
  200. CloseHandle( hDir );
  201. }
  202. else
  203. {
  204. CHAR pszErr[256];
  205. strcpy(pszErr, "Could not open ");
  206. strcat(pszErr, szRoot);
  207. cryAndDie(pszErr, 1);
  208. }
  209. // Write status line
  210. CHAR szFileName[MAX_PATH] = BUILDDEST;
  211. DWORD cTotal;
  212. int iBVTResult = ParseBVTLogfile( &szRoot[cchRoot], szFileName, &cTotal);
  213. if( iBVTResult == c_NoLog )
  214. {
  215. PrintToFile( hFile, " <TD ><FONT FACE=Arial ><CENTER><B>No Log</B></CENTER>\x0d\x0a" );
  216. }
  217. else if( iBVTResult == c_Toast )
  218. {
  219. PrintToFile( hFile, " <TD ><FONT FACE=Arial ><CENTER><B>Toast</B></CENTER>\x0d\x0a" );
  220. }
  221. /* else if ( iBVTResult <= 0 ) // Negative passed% of existing suites. Some suite(s) missing.
  222. {
  223. PrintToFile( hFile, " <TD ><FONT FACE=Arial ><CENTER><B><A HREF=\"%s\"> %d (Partial)</A></B></CENTER>\x0d\x0a", szFileName, -iBVTResult);
  224. }*/
  225. else
  226. {
  227. PrintToFile( hFile, " <TD ><FONT FACE=Arial ><CENTER><B><A HREF=\"%s\">%d%% of %d</A></B></CENTER>\x0d\x0a", szFileName, iBVTResult , cTotal);
  228. }
  229. PrintToFile( hFileSR, " <TD ><FONT FACE=Arial ><CENTER><B>N/A</B></CENTER>\x0d\x0a" );
  230. // Write Build number
  231. strcpy( szFileName, "\\\\b11nlbuilds\\sapi5\\Web.Files\\logs\\BuildAll\\BuildAllx86");
  232. strcat( szFileName, &szRoot[cchRoot] );
  233. strcat( szFileName, ".html" );
  234. PrintToFile( hFile, " <TD ><CENTER><B><A HREF=\"%s\">%s</A></B></CENTER>\n", szFileName, &szRoot[cchRoot] );
  235. PrintToFile( hFileSR, " <TD ><CENTER><B>%s</B></CENTER>\n", &szRoot[cchRoot] );
  236. *pTmp++ = '\\';
  237. // Write SAPI builds
  238. for (int j = 0; j < DIM(g_aSAPIfiles); ++j)
  239. {
  240. PrintToFile(hFile, " <TD BGCOLOR=\"%s\"><FONT FACE=Arial >", g_aSAPIfiles[j].szColor);
  241. strcpy( &szRoot[cchRoot + 5], g_aSAPIfiles[j].szRelativePath );
  242. // Create link to merge module directory
  243. if( !strcmp( "release\\msm\\x86", g_aSAPIfiles[j].szRelativePath) ||
  244. !strcmp( "debug\\msm\\x86", g_aSAPIfiles[j].szRelativePath) )
  245. {
  246. PrintToFile( hFile, "<A HREF=\"FILE://%s\"><B>%s</B></A>", szRoot, g_aSAPIfiles[j].szDescription );
  247. }
  248. // Create link to msi file
  249. else
  250. {
  251. hExistingFile = CreateFile( szRoot, GENERIC_READ, FILE_SHARE_READ, NULL,
  252. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  253. if( hExistingFile != INVALID_HANDLE_VALUE )
  254. {
  255. PrintToFile( hFile, "<A HREF=\"FILE://%s\"><B>%s</B></A>", szRoot, g_aSAPIfiles[j].szDescription );
  256. CloseHandle( hExistingFile );
  257. }
  258. else
  259. {
  260. PrintToFile( hFile, "<CENTER><B>N/A</B></CENTER>" );
  261. }
  262. }
  263. PrintToFile(hFile, "\x0d\x0a");
  264. }
  265. // Write SR builds.
  266. for (j = 0; j < DIM(g_aSRfiles); ++j)
  267. {
  268. PrintToFile(hFileSR, " <TD BGCOLOR=\"%s\"><FONT FACE=Arial >", g_aSRfiles[j].szColor);
  269. strcpy( &szRoot[cchRoot + 5], g_aSRfiles[j].szRelativePath );
  270. hExistingFile = CreateFile( szRoot, GENERIC_READ, FILE_SHARE_READ, NULL,
  271. OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
  272. if( hExistingFile != INVALID_HANDLE_VALUE )
  273. {
  274. PrintToFile( hFileSR, "<A HREF=FILE://%s><B>%s</B></A>", szRoot, g_aSRfiles[j].szDescription );
  275. CloseHandle( hExistingFile );
  276. }
  277. else
  278. {
  279. PrintToFile( hFileSR, "<CENTER><B>N/A</B></CENTER>" );
  280. }
  281. PrintToFile(hFileSR, "\x0d\x0a");
  282. }
  283. } while( pdirs < pEnd );
  284. system( "del dirs.txt" );
  285. PrintToFile( hFile, "</TABLE>\x0d\x0a<BR>\x0d\x0a\x0d\x0a</CENTER>\x0d\x0a</BODY></HTML>\x0d\x0a" );
  286. CloseHandle( hFile );
  287. PrintToFile( hFileSR, "</TABLE>\x0d\x0a<BR>\x0d\x0a\x0d\x0a</CENTER>\x0d\x0a</BODY></HTML>\x0d\x0a" );
  288. CloseHandle( hFileSR );
  289. return 0;
  290. }
  291. // Text parsing function which returns a DWORD indicating the percentage of BVT tests that
  292. // passed. This function returns c_Toast or c_NoLog upon failure.
  293. int ParseBVTLogfile( CHAR* pszBuildNumber, CHAR* pszFileName , DWORD* pcTotal ) // output filename
  294. {
  295. // bool fDllMissing = false;
  296. DWORD cCrashed = 0, cPassed = 0, cSkipped = 0, cOther = 0;
  297. *pcTotal = 0;
  298. strcpy( pszFileName, BUILDDEST );
  299. strcat( pszFileName, pszBuildNumber );
  300. strcat( pszFileName, "\\release\\bvt\\x86\\bvtresults" );
  301. strcat( pszFileName, pszBuildNumber );
  302. strcat( pszFileName, ".txt" );
  303. CHAR* pszFileText = GetFileText(pszFileName, NULL);
  304. if(pszFileText == NULL)
  305. {
  306. pszFileName[0] = '\0';
  307. return c_NoLog;
  308. }
  309. _strupr(pszFileText);
  310. /*
  311. const char* apszDllName[] =
  312. {
  313. "ambvt.dll",
  314. "cfgengbvt.dll",
  315. "gramcompbvt.dll",
  316. "lexbvt.dll",
  317. "rmbvt.dll",
  318. "srbvt.dll",
  319. "ttsbvt.dll",
  320. };
  321. for(int i = 0; i < sizeof(apszDllName) / sizeof(apszDllName[0]); i++)
  322. {
  323. char szDllName[64];
  324. strcpy(szDllName, apszDllName[i]);
  325. if(strstr(pszFileText, _strupr(szDllName)) == NULL)
  326. {
  327. fDllMissing = true;
  328. break;
  329. }
  330. }
  331. */
  332. const char* cpszBeginCase = "BEGIN TEST:";
  333. const char* cpszEndCase = "END TEST:";
  334. CHAR* pCur;
  335. // Assume srengbvt runs last. Truncate it's results.
  336. // TODO
  337. // pCur = strstr(pCur, "srengbvt.dll");
  338. // if(pCur) *pCur = 0;
  339. CHAR* pNext = NULL;
  340. for(pCur = strstr(pszFileText, cpszBeginCase); pCur; pCur = pNext)
  341. {
  342. pCur++;
  343. pNext = strstr(pCur, cpszBeginCase);
  344. if(pNext) *pNext = 0;
  345. if(strstr(pCur, "SRENGBVT.DLL")) continue;
  346. (*pcTotal)++;
  347. pCur = strstr(pCur, cpszEndCase);
  348. if(pCur == NULL)
  349. {
  350. cCrashed++;
  351. continue;
  352. }
  353. CHAR* pTemp = strstr(pCur, "TIME=");
  354. if(pTemp)
  355. {
  356. *pTemp = 0; // avoid accidental result
  357. }
  358. else
  359. {
  360. return c_Toast; // should never happen!
  361. }
  362. if(strstr(pCur, " PASSED, "))
  363. {
  364. cPassed++;
  365. }
  366. else if(strstr(pCur, " SKIPPED, "))
  367. {
  368. cSkipped++;
  369. }
  370. else
  371. {
  372. cOther++;
  373. }
  374. }
  375. // return *pcTotal ? int((fDllMissing ? -100.0 : 100.0) * cPassed / (*pcTotal - cSkipped)) : c_Toast;
  376. return (*pcTotal) ? int(100.0 * cPassed / ((*pcTotal) - cSkipped)) : c_Toast;
  377. }