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.

632 lines
18 KiB

  1. #include "stdafx.h"
  2. #include "mon.h"
  3. TCHAR gszMsg[256];
  4. TCHAR gszInputFileName[512];
  5. int compareMonitors(CMonitor *p1, CMonitor *p2)
  6. {
  7. return (stricmp(&p1->ID[8], &p2->ID[8]));
  8. }
  9. int compareManufacturers(CManufacturer *p1, CManufacturer *p2)
  10. {
  11. return (stricmp(p1->name, p2->name));
  12. }
  13. ////////////////////////////////////////////////////////////////////
  14. // Strip off blank lines and comments
  15. VOID TokenizeInf(LPSTR orgBuf, CMonitorInf *pMonitorInf)
  16. {
  17. LPSTR linePtr = orgBuf, startPtr, endPtr, outPtr = orgBuf;
  18. strcat(orgBuf, "\n");
  19. pMonitorInf->numLines = 0;
  20. while (1)
  21. {
  22. startPtr = linePtr;
  23. endPtr = strchr(linePtr, '\n');
  24. if (endPtr == NULL)
  25. break;
  26. else
  27. linePtr = endPtr+1;
  28. *endPtr = '\0';
  29. // Remove leading space
  30. while (*startPtr <= ' ' && *startPtr != '\0')
  31. startPtr++;
  32. if (strchr(startPtr, ';'))
  33. endPtr = strchr(startPtr, ';');
  34. //remove trailing space
  35. while (startPtr != endPtr)
  36. {
  37. if (*(endPtr-1) > ' ')
  38. break;
  39. endPtr--;
  40. }
  41. *endPtr = '\0';
  42. // If not blank line, put it back to buf
  43. if (*startPtr != '\0')
  44. {
  45. pMonitorInf->lines[pMonitorInf->numLines] = outPtr;
  46. pMonitorInf->numLines++;
  47. ASSERT(pMonitorInf->numLines < MAX_LINE_NUMBER);
  48. while (*startPtr != '\0')
  49. {
  50. *outPtr = *startPtr;
  51. startPtr++; outPtr++;
  52. }
  53. *outPtr = '\0';
  54. outPtr++;
  55. }
  56. }
  57. *outPtr = '\0';
  58. LPSECTION pSection = &pMonitorInf->sections[0];
  59. pMonitorInf->numSections = 0;
  60. for (UINT line = 0;
  61. line < pMonitorInf->numLines;
  62. line++)
  63. {
  64. LPSTR ptr = pMonitorInf->lines[line];
  65. if (*ptr == '[')
  66. {
  67. pSection = &pMonitorInf->sections[pMonitorInf->numSections];
  68. pSection->startLine = pSection->endLine = line;
  69. pMonitorInf->numSections++;
  70. ASSERT(strlen(ptr) <= 250);
  71. ASSERT(pMonitorInf->numSections < MAX_SECTION_NUMBER);
  72. strcpy(pSection->name, ptr+1);
  73. ptr = strchr(pSection->name, ']');
  74. ASSERT(ptr != NULL);
  75. *ptr = '\0';
  76. CString sectionName(pSection->name);
  77. sectionName.MakeUpper();
  78. strcpy(pSection->name, sectionName);
  79. }
  80. else
  81. pSection->endLine = line;
  82. }
  83. }
  84. UINT TokenOneLine(LPSTR line, CHAR token, LPSTR *tokens)
  85. {
  86. UINT numToken = 0;
  87. LPSTR ptr;;
  88. while (ptr = strchr(line, token))
  89. {
  90. tokens[numToken] = line;
  91. *ptr = '\0';
  92. line = ptr + 1;
  93. numToken++;
  94. }
  95. tokens[numToken] = line;
  96. numToken++;
  97. /////////////////////////////////////////////
  98. // Remove leading and trailing spaces
  99. for (UINT i = 0; i < numToken; i++)
  100. {
  101. ptr = tokens[i];
  102. while (*ptr <= ' ' && *ptr != '\0')
  103. ptr++;
  104. tokens[i] = ptr;
  105. ptr = ptr+strlen(ptr);
  106. while (ptr != tokens[i])
  107. {
  108. if (*(ptr-1) > ' ')
  109. break;
  110. ptr--;
  111. }
  112. *ptr = '\0';
  113. }
  114. return numToken;
  115. }
  116. CManufacturer::~CManufacturer()
  117. {
  118. for (int i = 0; i < MonitorArray.GetSize(); i++)
  119. delete ((CMonitor *)MonitorArray[i]);
  120. MonitorArray.RemoveAll();
  121. m_MonitorIDArray.RemoveAll();
  122. }
  123. CMonitorInf::~CMonitorInf()
  124. {
  125. for (int i = 0; i < ManufacturerArray.GetSize(); i++)
  126. delete ((CManufacturer *)ManufacturerArray[i]);
  127. ManufacturerArray.RemoveAll();
  128. if (pReadFileBuf)
  129. free(pReadFileBuf);
  130. }
  131. BOOL CMonitorInf::ParseInf(VOID)
  132. {
  133. LPSECTION pSection = SeekSection("version");
  134. if (pSection == NULL)
  135. return FALSE;
  136. /////////////////////////////////////////////////////
  137. // Confirm it's Monitor Class
  138. for (UINT i = pSection->startLine + 1;
  139. i <= pSection->endLine;
  140. i++)
  141. {
  142. strcpy(m_lineBuf, lines[i]);
  143. if (TokenOneLine(m_lineBuf, '=', m_tokens) != 2)
  144. return FALSE;
  145. if (stricmp(m_tokens[0], "Class") == 0 &&
  146. stricmp(m_tokens[1], "Monitor") == 0)
  147. break;
  148. }
  149. if (i > pSection->endLine)
  150. return FALSE;
  151. /////////////////////////////////////////////////////
  152. // Look for Manufacturers
  153. //
  154. // [Manufacturer]
  155. // %MagCompu%=MagCompu
  156. pSection = SeekSection("Manufacturer");
  157. if (pSection == NULL)
  158. return FALSE;
  159. for (i = pSection->startLine + 1;
  160. i <= pSection->endLine;
  161. i++)
  162. {
  163. strcpy(m_lineBuf, lines[i]);
  164. if (TokenOneLine(m_lineBuf, '=', m_tokens) != 2)
  165. {
  166. ASSERT(FALSE);
  167. return FALSE;
  168. }
  169. ////////////////////////////////////////////////////////////
  170. // Microsoft Generic is special. Need to be added manually
  171. if (stricmp(m_tokens[1], "Generic") == 0)
  172. continue;
  173. CManufacturer *pManufacturer = new(CManufacturer);
  174. if (pManufacturer == NULL)
  175. {
  176. ASSERT(FALSE);
  177. return FALSE;
  178. }
  179. strcpy(pManufacturer->name, m_tokens[1]);
  180. strcpy(pManufacturer->AliasName, m_tokens[0]);
  181. if (!ParseOneManufacturer(pManufacturer))
  182. {
  183. sprintf(gszMsg, "Manufacturer %s contains empty contents.",
  184. &pManufacturer->name);
  185. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  186. ASSERT(FALSE);
  187. return FALSE;
  188. }
  189. /////////////////////////////////////////////////
  190. // Insert the manufacturer into the array.
  191. // It's sorted by name
  192. int comp = 1;
  193. for (int k = 0; k < ManufacturerArray.GetSize(); k++)
  194. {
  195. CManufacturer *pMan = (CManufacturer *)ManufacturerArray[k];
  196. comp = compareManufacturers(pManufacturer, pMan);
  197. if (comp > 0)
  198. continue;
  199. else if (comp < 0)
  200. break;
  201. ////////////////////////////////////////////
  202. // Duplicated Manufacturer in one inf ?
  203. ASSERT(FALSE);
  204. break;
  205. }
  206. if (comp == 0)
  207. {
  208. delete pManufacturer;
  209. }
  210. else
  211. {
  212. ManufacturerArray.InsertAt(k, (LPVOID)pManufacturer);
  213. }
  214. }
  215. ///////////////////////////////////////////////////////
  216. // Remove Manufacturers with empty monitors
  217. Pack();
  218. ASSERT(FillupAlias());
  219. return TRUE;
  220. }
  221. BOOL CMonitorInf::ParseOneManufacturer(CManufacturer *pManufacturer)
  222. {
  223. ///////////////////////////////////////////////////////////
  224. // [NEC]
  225. // %NEC-XE15%=NEC-XE15, Monitor\NEC3C00
  226. LPSECTION pSection = SeekSection(pManufacturer->name);
  227. if (pSection == NULL)
  228. return FALSE;
  229. for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++)
  230. {
  231. strcpy(m_lineBuf, lines[i]);
  232. if (TokenOneLine(m_lineBuf, '=', m_tokens) != 2)
  233. {
  234. ASSERT(FALSE);
  235. return FALSE;
  236. }
  237. UINT k = TokenOneLine(m_tokens[1], ',', &m_tokens[2]);
  238. if (k == 1)
  239. continue;
  240. else if (k != 2)
  241. {
  242. sprintf(gszMsg, "Manufacturer %s has a bad monitor line %s",
  243. &pManufacturer->name, lines[i]);
  244. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  245. ASSERT(FALSE);
  246. return FALSE;
  247. }
  248. ///////////////////////////////////////////////////////////
  249. // Ignore non-pnp monitors
  250. if (strnicmp(m_tokens[3], "Monitor\\", strlen("Monitor\\")))
  251. continue;
  252. if (strlen(m_tokens[3]) != strlen("Monitor\\NEC3C00"))
  253. {
  254. sprintf(gszMsg, "Manufacturer %s has a bad monitor line %s",
  255. &pManufacturer->name, lines[i]);
  256. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  257. ASSERT(FALSE);
  258. continue;
  259. }
  260. CMonitor *pMonitor = new(CMonitor);
  261. if (pMonitor == NULL)
  262. {
  263. ASSERT(FALSE);
  264. return FALSE;
  265. }
  266. strcpy(pMonitor->AliasName, m_tokens[0]);
  267. strcpy(pMonitor->InstallSectionName, m_tokens[2]);
  268. strcpy(pMonitor->ID, m_tokens[3]);
  269. for (k = 8; k < (UINT)lstrlen(pMonitor->ID); k++)
  270. pMonitor->ID[k] = toupper(pMonitor->ID[k]);
  271. if (!ParseOneMonitor(pMonitor))
  272. {
  273. ASSERT(FALSE);
  274. return FALSE;
  275. }
  276. /////////////////////////////////////////////////
  277. // Insert the monitor into the array.
  278. // It's sorted by ID
  279. int comp = 1;
  280. for (k = 0; k < (UINT)pManufacturer->MonitorArray.GetSize(); k++)
  281. {
  282. CMonitor *pMon = (CMonitor *)pManufacturer->MonitorArray[k];
  283. comp = compareMonitors(pMonitor, pMon);
  284. if (comp > 0)
  285. continue;
  286. else if (comp < 0)
  287. break;
  288. ////////////////////////////////////////////
  289. // Duplicated Monitor ?
  290. sprintf(gszMsg, "Manufacturer %s has duplicated monitor line %s",
  291. &pManufacturer->name, &pMonitor->ID[8]);
  292. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  293. ASSERT(FALSE);
  294. break;
  295. }
  296. if (comp == 0)
  297. {
  298. delete pMonitor;
  299. }
  300. else
  301. {
  302. pManufacturer->MonitorArray.InsertAt(k, (LPVOID)pMonitor);
  303. }
  304. }
  305. return TRUE;
  306. }
  307. BOOL CMonitorInf::ParseOneMonitor(CMonitor *pMonitor)
  308. {
  309. ///////////////////////////////////////////////////////////
  310. // [NEC-XE15]
  311. // DelReg=DCR
  312. // AddReg=NEC-XE15.Add, 1280, DPMS, ICM12
  313. //
  314. // [NEC-XE15.Add]
  315. // HKR,"MODES\1024,768",Mode1,,"31.0-65.0,55.0-120.0,+,+"
  316. LPSECTION pSection = SeekSection(pMonitor->InstallSectionName);
  317. if (pSection == NULL)
  318. {
  319. sprintf(gszMsg, "Monitor %s/%s misses InstallSection\n",
  320. &pMonitor->ID[8], pMonitor->InstallSectionName);
  321. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  322. ASSERT(FALSE);
  323. return FALSE;
  324. }
  325. for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++)
  326. {
  327. TCHAR buf[256];
  328. strcpy(buf, lines[i]);
  329. if (TokenOneLine(buf, '=', m_tokens) != 2)
  330. {
  331. ASSERT(FALSE);
  332. return FALSE;
  333. }
  334. if (stricmp(m_tokens[0], "DelReg") == 0)
  335. {
  336. ASSERT(TokenOneLine(m_tokens[1], ',', &m_tokens[2]) == 1);
  337. }
  338. else if (stricmp(m_tokens[0], "AddReg") == 0)
  339. {
  340. int numAddReg = TokenOneLine(m_tokens[1], ',', &m_tokens[2]);
  341. strcpy(pMonitor->AddRegSectionName, m_tokens[2]);
  342. for (int j = 1; j < numAddReg; j++)
  343. {
  344. //////////////////////////////////////////////////////
  345. // Ignore ICM sectione
  346. if (strnicmp(m_tokens[j+2], "ICM", lstrlen("ICM")) == 0)
  347. continue;
  348. LPSECTION pSection1 = SeekSection(m_tokens[j+2]);
  349. if (pSection1 == NULL)
  350. {
  351. sprintf(gszMsg, "Monitor %s/%s misses common InstallSection %s\n",
  352. &pMonitor->ID[8], pMonitor->InstallSectionName, m_tokens[j+2]);
  353. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  354. ASSERT(FALSE);
  355. return FALSE;
  356. }
  357. ASSERT(pSection1->endLine == (pSection1->startLine+1));
  358. pMonitor->CommonSects[pMonitor->numCommonSects] =
  359. gCommonSections.AddOneSection(m_tokens[j+2], lines[pSection1->endLine]);
  360. pMonitor->numCommonSects++;
  361. }
  362. }
  363. }
  364. pSection = SeekSection(pMonitor->AddRegSectionName);
  365. if (pSection == NULL)
  366. {
  367. sprintf(gszMsg, "Monitor %s/%s misses AddRegSection %s\n",
  368. &pMonitor->ID[8], pMonitor->InstallSectionName, pMonitor->AddRegSectionName);
  369. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  370. ASSERT(FALSE);
  371. return FALSE;
  372. }
  373. int lenBuf = 0;
  374. for (i = pSection->startLine + 1; i <= pSection->endLine; i++)
  375. {
  376. lenBuf += strlen(lines[i])+3;
  377. }
  378. if (lenBuf == 0)
  379. {
  380. sprintf(gszMsg, "Monitor %s/%s has empty AddRegSection\n",
  381. &pMonitor->ID[8], pMonitor->InstallSectionName);
  382. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  383. ASSERT(FALSE);
  384. }
  385. pMonitor->AddRegSectionBuf = (LPSTR)malloc(sizeof(TCHAR)*lenBuf);
  386. if (pMonitor->AddRegSectionBuf == NULL)
  387. {
  388. ASSERT(FALSE);
  389. return FALSE;
  390. }
  391. pMonitor->AddRegSectionBuf[0] = '\0';
  392. for (i = pSection->startLine + 1; i <= pSection->endLine; i++)
  393. {
  394. if ((strnicmp(lines[i], "HKR,\"MODES\\", lstrlen("HKR,\"MODES\\")) == 0) ||
  395. (stricmp(lines[i], "HKR,,DPMS,,0") == 0))
  396. {
  397. sprintf(pMonitor->AddRegSectionBuf + strlen(pMonitor->AddRegSectionBuf),
  398. "%s\n", lines[i]);
  399. }
  400. else if (strnicmp(lines[i], "HKR,,ICMProfile,0,", lstrlen("HKR,,ICMProfile,1,")) == 0)
  401. {
  402. }
  403. //////////////////////////////////////////////////////////////
  404. // Anything other than modes, put them into common section
  405. else if (strnicmp(lines[i], "HKR,,ICMProfile,1,", lstrlen("HKR,,ICMProfile,1,")) == 0)
  406. {
  407. // Ignore ICMs
  408. /*
  409. TCHAR buf[16];
  410. LPSTR ptr = lines[i] + lstrlen("HKR,,ICMProfile,1,"), stopPtr;
  411. ASSERT(lstrlen(ptr) == 1 || lstrlen(ptr) == 2);
  412. *ptr = tolower(*ptr);
  413. long icmNum = strtoul(ptr, &stopPtr, 16);
  414. sprintf(buf, "ICM%d", icmNum);
  415. pMonitor->CommonSects[pMonitor->numCommonSects] =
  416. gCommonSections.AddOneSection(buf, lines[i]);
  417. pMonitor->numCommonSects++;
  418. */
  419. }
  420. else if (stricmp(lines[i], "HKR,,DPMS,,1") == 0)
  421. {
  422. pMonitor->CommonSects[pMonitor->numCommonSects] =
  423. gCommonSections.AddOneSection("DPMS", lines[i]);
  424. pMonitor->numCommonSects++;
  425. }
  426. else if (strnicmp(lines[i], "HKR,,MaxResolution,,\"", lstrlen("HKR,,MaxResolution,,\"")) == 0)
  427. {
  428. TCHAR buf[64];
  429. LPSTR ptr;
  430. strcpy(buf, lines[i] + lstrlen("HKR,,MaxResolution,,\""));
  431. ptr = strchr(buf, ',');
  432. ASSERT(ptr != NULL);
  433. *ptr = '\0';
  434. pMonitor->CommonSects[pMonitor->numCommonSects] =
  435. gCommonSections.AddOneSection(buf, lines[i]);
  436. pMonitor->numCommonSects++;
  437. }
  438. /////////////////////////////////////////////////////////////////////////
  439. // Something common in specific Manufacturers
  440. else if ((strnicmp(lines[i], "HKR,,LF,0,1", lstrlen("HKR,,LF,0,1")) == 0) ||
  441. (strnicmp(lines[i], "HKR,,VE,0,1", lstrlen("HKR,,LF,0,1")) == 0))
  442. {
  443. }
  444. else
  445. {
  446. sprintf(gszMsg, "Monitor %s/%s has unexpected AddReg Section %s",
  447. &pMonitor->ID[8], pMonitor->InstallSectionName, lines[i]);
  448. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  449. ASSERT(FALSE);
  450. }
  451. }
  452. return TRUE;
  453. }
  454. LPSECTION CMonitorInf::SeekSection(LPCSTR sectionName)
  455. {
  456. for (UINT i = 0; i < numSections; i++)
  457. {
  458. if (stricmp(sections[i].name, sectionName) == 0)
  459. return &sections[i];
  460. }
  461. return NULL;
  462. }
  463. VOID CMonitorInf::Pack(VOID)
  464. {
  465. for (int i = 0; i < ManufacturerArray.GetSize(); i++)
  466. {
  467. CManufacturer *pManufacturer = (CManufacturer*)ManufacturerArray[i];
  468. if (pManufacturer->MonitorArray.GetSize() == 0)
  469. {
  470. delete pManufacturer;
  471. ManufacturerArray.RemoveAt(i);
  472. i--;
  473. }
  474. }
  475. }
  476. LPCOMMON_ALIAS CMonitorInf::LookupCommonAlias(LPCSTR lpAliasName, LPCOMMON_ALIAS AliasHead, UINT numAlias)
  477. {
  478. TCHAR name[64];
  479. lstrcpy(name, lpAliasName+1);
  480. ASSERT(lpAliasName[0] == '%');
  481. ASSERT(lpAliasName[lstrlen(name)] == '%');
  482. name[lstrlen(name)-1] = '\0';
  483. for (UINT i = 0; i < numAlias; i++)
  484. {
  485. if (stricmp(name, AliasHead[i].lpAlias) == 0)
  486. return &AliasHead[i];
  487. }
  488. return NULL;
  489. }
  490. BOOL CMonitorInf::FillupAlias(VOID)
  491. {
  492. /////////////////////////////////////////////////////////////////////
  493. // First read in all strings
  494. LPSECTION pSection = SeekSection("Strings");
  495. if (pSection == NULL)
  496. {
  497. ASSERT(FALSE);
  498. return FALSE;
  499. }
  500. int numAlias = pSection->endLine - pSection->startLine;
  501. ASSERT(numAlias > 0);
  502. LPCOMMON_ALIAS pInfAlias = (LPCOMMON_ALIAS)malloc(numAlias * sizeof(COMMON_ALIAS));
  503. if (pInfAlias == NULL)
  504. {
  505. ASSERT(FALSE);
  506. return FALSE;
  507. }
  508. LPCOMMON_ALIAS pAlias = pInfAlias;
  509. for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++, pAlias++)
  510. {
  511. if (TokenOneLine(lines[i], '=', m_tokens) != 2)
  512. {
  513. sprintf(gszMsg, "A wrong string line %s.", lines[i]);
  514. MessageBox(NULL, gszMsg, gszInputFileName, MB_OK);
  515. ASSERT(FALSE);
  516. free(pInfAlias);
  517. return FALSE;
  518. }
  519. pAlias->lpAlias = m_tokens[0];
  520. pAlias->lpContents = m_tokens[1];
  521. ASSERT(pAlias->lpContents[0] == '\"');
  522. }
  523. //////////////////////////////////////////////////////////
  524. // Go through Manufacturers and Monitors to fill up alias
  525. for (i = 0; i < (UINT)ManufacturerArray.GetSize(); i++)
  526. {
  527. CManufacturer *pManufacturer = (CManufacturer*)ManufacturerArray[i];
  528. pAlias = LookupCommonAlias(pManufacturer->AliasName, pInfAlias, numAlias);
  529. if (pAlias == NULL)
  530. {
  531. ASSERT(FALSE);
  532. free(pInfAlias);
  533. return FALSE;
  534. }
  535. pAlias = gCommonAlias.AddOneAlias(pAlias->lpAlias, pAlias->lpContents);
  536. if (pAlias == NULL)
  537. {
  538. ASSERT(FALSE);
  539. free(pInfAlias);
  540. return FALSE;
  541. }
  542. pManufacturer->pAlias = pAlias;
  543. for (int j = 0; j < pManufacturer->MonitorArray.GetSize(); j++)
  544. {
  545. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[j];
  546. pAlias = LookupCommonAlias(pMonitor->AliasName, pInfAlias, numAlias);
  547. if (pAlias == NULL)
  548. {
  549. ASSERT(FALSE);
  550. free(pInfAlias);
  551. return FALSE;
  552. }
  553. pAlias = gCommonAlias.AddOneAlias(pAlias->lpAlias, pAlias->lpContents);
  554. if (pAlias == NULL)
  555. {
  556. ASSERT(FALSE);
  557. free(pInfAlias);
  558. return FALSE;
  559. }
  560. pMonitor->pAlias = pAlias;
  561. }
  562. }
  563. free(pInfAlias);
  564. return TRUE;
  565. }