#include "stdafx.h" #include "mon.h" TCHAR gszMsg[256]; TCHAR gszInputFileName[512]; int compareMonitors(CMonitor *p1, CMonitor *p2) { return (stricmp(&p1->ID[8], &p2->ID[8])); } int compareManufacturers(CManufacturer *p1, CManufacturer *p2) { return (stricmp(p1->name, p2->name)); } //////////////////////////////////////////////////////////////////// // Strip off blank lines and comments VOID TokenizeInf(LPSTR orgBuf, CMonitorInf *pMonitorInf) { LPSTR linePtr = orgBuf, startPtr, endPtr, outPtr = orgBuf; strcat(orgBuf, "\n"); pMonitorInf->numLines = 0; while (1) { startPtr = linePtr; endPtr = strchr(linePtr, '\n'); if (endPtr == NULL) break; else linePtr = endPtr+1; *endPtr = '\0'; // Remove leading space while (*startPtr <= ' ' && *startPtr != '\0') startPtr++; if (strchr(startPtr, ';')) endPtr = strchr(startPtr, ';'); //remove trailing space while (startPtr != endPtr) { if (*(endPtr-1) > ' ') break; endPtr--; } *endPtr = '\0'; // If not blank line, put it back to buf if (*startPtr != '\0') { pMonitorInf->lines[pMonitorInf->numLines] = outPtr; pMonitorInf->numLines++; ASSERT(pMonitorInf->numLines < MAX_LINE_NUMBER); while (*startPtr != '\0') { *outPtr = *startPtr; startPtr++; outPtr++; } *outPtr = '\0'; outPtr++; } } *outPtr = '\0'; LPSECTION pSection = &pMonitorInf->sections[0]; pMonitorInf->numSections = 0; for (UINT line = 0; line < pMonitorInf->numLines; line++) { LPSTR ptr = pMonitorInf->lines[line]; if (*ptr == '[') { pSection = &pMonitorInf->sections[pMonitorInf->numSections]; pSection->startLine = pSection->endLine = line; pMonitorInf->numSections++; ASSERT(strlen(ptr) <= 250); ASSERT(pMonitorInf->numSections < MAX_SECTION_NUMBER); strcpy(pSection->name, ptr+1); ptr = strchr(pSection->name, ']'); ASSERT(ptr != NULL); *ptr = '\0'; CString sectionName(pSection->name); sectionName.MakeUpper(); strcpy(pSection->name, sectionName); } else pSection->endLine = line; } } UINT TokenOneLine(LPSTR line, CHAR token, LPSTR *tokens) { UINT numToken = 0; LPSTR ptr;; while (ptr = strchr(line, token)) { tokens[numToken] = line; *ptr = '\0'; line = ptr + 1; numToken++; } tokens[numToken] = line; numToken++; ///////////////////////////////////////////// // Remove leading and trailing spaces for (UINT i = 0; i < numToken; i++) { ptr = tokens[i]; while (*ptr <= ' ' && *ptr != '\0') ptr++; tokens[i] = ptr; ptr = ptr+strlen(ptr); while (ptr != tokens[i]) { if (*(ptr-1) > ' ') break; ptr--; } *ptr = '\0'; } return numToken; } CManufacturer::~CManufacturer() { for (int i = 0; i < MonitorArray.GetSize(); i++) delete ((CMonitor *)MonitorArray[i]); MonitorArray.RemoveAll(); m_MonitorIDArray.RemoveAll(); } CMonitorInf::~CMonitorInf() { for (int i = 0; i < ManufacturerArray.GetSize(); i++) delete ((CManufacturer *)ManufacturerArray[i]); ManufacturerArray.RemoveAll(); if (pReadFileBuf) free(pReadFileBuf); } BOOL CMonitorInf::ParseInf(VOID) { LPSECTION pSection = SeekSection("version"); if (pSection == NULL) return FALSE; ///////////////////////////////////////////////////// // Confirm it's Monitor Class for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++) { strcpy(m_lineBuf, lines[i]); if (TokenOneLine(m_lineBuf, '=', m_tokens) != 2) return FALSE; if (stricmp(m_tokens[0], "Class") == 0 && stricmp(m_tokens[1], "Monitor") == 0) break; } if (i > pSection->endLine) return FALSE; ///////////////////////////////////////////////////// // Look for Manufacturers // // [Manufacturer] // %MagCompu%=MagCompu pSection = SeekSection("Manufacturer"); if (pSection == NULL) return FALSE; for (i = pSection->startLine + 1; i <= pSection->endLine; i++) { strcpy(m_lineBuf, lines[i]); if (TokenOneLine(m_lineBuf, '=', m_tokens) != 2) { ASSERT(FALSE); return FALSE; } //////////////////////////////////////////////////////////// // Microsoft Generic is special. Need to be added manually if (stricmp(m_tokens[1], "Generic") == 0) continue; CManufacturer *pManufacturer = new(CManufacturer); if (pManufacturer == NULL) { ASSERT(FALSE); return FALSE; } strcpy(pManufacturer->name, m_tokens[1]); strcpy(pManufacturer->AliasName, m_tokens[0]); if (!ParseOneManufacturer(pManufacturer)) { sprintf(gszMsg, "Manufacturer %s contains empty contents.", &pManufacturer->name); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); return FALSE; } ///////////////////////////////////////////////// // Insert the manufacturer into the array. // It's sorted by name int comp = 1; for (int k = 0; k < ManufacturerArray.GetSize(); k++) { CManufacturer *pMan = (CManufacturer *)ManufacturerArray[k]; comp = compareManufacturers(pManufacturer, pMan); if (comp > 0) continue; else if (comp < 0) break; //////////////////////////////////////////// // Duplicated Manufacturer in one inf ? ASSERT(FALSE); break; } if (comp == 0) { delete pManufacturer; } else { ManufacturerArray.InsertAt(k, (LPVOID)pManufacturer); } } /////////////////////////////////////////////////////// // Remove Manufacturers with empty monitors Pack(); ASSERT(FillupAlias()); return TRUE; } BOOL CMonitorInf::ParseOneManufacturer(CManufacturer *pManufacturer) { /////////////////////////////////////////////////////////// // [NEC] // %NEC-XE15%=NEC-XE15, Monitor\NEC3C00 LPSECTION pSection = SeekSection(pManufacturer->name); if (pSection == NULL) return FALSE; for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++) { strcpy(m_lineBuf, lines[i]); if (TokenOneLine(m_lineBuf, '=', m_tokens) != 2) { ASSERT(FALSE); return FALSE; } UINT k = TokenOneLine(m_tokens[1], ',', &m_tokens[2]); if (k == 1) continue; else if (k != 2) { sprintf(gszMsg, "Manufacturer %s has a bad monitor line %s", &pManufacturer->name, lines[i]); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); return FALSE; } /////////////////////////////////////////////////////////// // Ignore non-pnp monitors if (strnicmp(m_tokens[3], "Monitor\\", strlen("Monitor\\"))) continue; if (strlen(m_tokens[3]) != strlen("Monitor\\NEC3C00")) { sprintf(gszMsg, "Manufacturer %s has a bad monitor line %s", &pManufacturer->name, lines[i]); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); continue; } CMonitor *pMonitor = new(CMonitor); if (pMonitor == NULL) { ASSERT(FALSE); return FALSE; } strcpy(pMonitor->AliasName, m_tokens[0]); strcpy(pMonitor->InstallSectionName, m_tokens[2]); strcpy(pMonitor->ID, m_tokens[3]); for (k = 8; k < (UINT)lstrlen(pMonitor->ID); k++) pMonitor->ID[k] = toupper(pMonitor->ID[k]); if (!ParseOneMonitor(pMonitor)) { ASSERT(FALSE); return FALSE; } ///////////////////////////////////////////////// // Insert the monitor into the array. // It's sorted by ID int comp = 1; for (k = 0; k < (UINT)pManufacturer->MonitorArray.GetSize(); k++) { CMonitor *pMon = (CMonitor *)pManufacturer->MonitorArray[k]; comp = compareMonitors(pMonitor, pMon); if (comp > 0) continue; else if (comp < 0) break; //////////////////////////////////////////// // Duplicated Monitor ? sprintf(gszMsg, "Manufacturer %s has duplicated monitor line %s", &pManufacturer->name, &pMonitor->ID[8]); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); break; } if (comp == 0) { delete pMonitor; } else { pManufacturer->MonitorArray.InsertAt(k, (LPVOID)pMonitor); } } return TRUE; } BOOL CMonitorInf::ParseOneMonitor(CMonitor *pMonitor) { /////////////////////////////////////////////////////////// // [NEC-XE15] // DelReg=DCR // AddReg=NEC-XE15.Add, 1280, DPMS, ICM12 // // [NEC-XE15.Add] // HKR,"MODES\1024,768",Mode1,,"31.0-65.0,55.0-120.0,+,+" LPSECTION pSection = SeekSection(pMonitor->InstallSectionName); if (pSection == NULL) { sprintf(gszMsg, "Monitor %s/%s misses InstallSection\n", &pMonitor->ID[8], pMonitor->InstallSectionName); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); return FALSE; } for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++) { TCHAR buf[256]; strcpy(buf, lines[i]); if (TokenOneLine(buf, '=', m_tokens) != 2) { ASSERT(FALSE); return FALSE; } if (stricmp(m_tokens[0], "DelReg") == 0) { ASSERT(TokenOneLine(m_tokens[1], ',', &m_tokens[2]) == 1); } else if (stricmp(m_tokens[0], "AddReg") == 0) { int numAddReg = TokenOneLine(m_tokens[1], ',', &m_tokens[2]); strcpy(pMonitor->AddRegSectionName, m_tokens[2]); for (int j = 1; j < numAddReg; j++) { ////////////////////////////////////////////////////// // Ignore ICM sectione if (strnicmp(m_tokens[j+2], "ICM", lstrlen("ICM")) == 0) continue; LPSECTION pSection1 = SeekSection(m_tokens[j+2]); if (pSection1 == NULL) { sprintf(gszMsg, "Monitor %s/%s misses common InstallSection %s\n", &pMonitor->ID[8], pMonitor->InstallSectionName, m_tokens[j+2]); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); return FALSE; } ASSERT(pSection1->endLine == (pSection1->startLine+1)); pMonitor->CommonSects[pMonitor->numCommonSects] = gCommonSections.AddOneSection(m_tokens[j+2], lines[pSection1->endLine]); pMonitor->numCommonSects++; } } } pSection = SeekSection(pMonitor->AddRegSectionName); if (pSection == NULL) { sprintf(gszMsg, "Monitor %s/%s misses AddRegSection %s\n", &pMonitor->ID[8], pMonitor->InstallSectionName, pMonitor->AddRegSectionName); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); return FALSE; } int lenBuf = 0; for (i = pSection->startLine + 1; i <= pSection->endLine; i++) { lenBuf += strlen(lines[i])+3; } if (lenBuf == 0) { sprintf(gszMsg, "Monitor %s/%s has empty AddRegSection\n", &pMonitor->ID[8], pMonitor->InstallSectionName); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); } pMonitor->AddRegSectionBuf = (LPSTR)malloc(sizeof(TCHAR)*lenBuf); if (pMonitor->AddRegSectionBuf == NULL) { ASSERT(FALSE); return FALSE; } pMonitor->AddRegSectionBuf[0] = '\0'; for (i = pSection->startLine + 1; i <= pSection->endLine; i++) { if ((strnicmp(lines[i], "HKR,\"MODES\\", lstrlen("HKR,\"MODES\\")) == 0) || (stricmp(lines[i], "HKR,,DPMS,,0") == 0)) { sprintf(pMonitor->AddRegSectionBuf + strlen(pMonitor->AddRegSectionBuf), "%s\n", lines[i]); } else if (strnicmp(lines[i], "HKR,,ICMProfile,0,", lstrlen("HKR,,ICMProfile,1,")) == 0) { } ////////////////////////////////////////////////////////////// // Anything other than modes, put them into common section else if (strnicmp(lines[i], "HKR,,ICMProfile,1,", lstrlen("HKR,,ICMProfile,1,")) == 0) { // Ignore ICMs /* TCHAR buf[16]; LPSTR ptr = lines[i] + lstrlen("HKR,,ICMProfile,1,"), stopPtr; ASSERT(lstrlen(ptr) == 1 || lstrlen(ptr) == 2); *ptr = tolower(*ptr); long icmNum = strtoul(ptr, &stopPtr, 16); sprintf(buf, "ICM%d", icmNum); pMonitor->CommonSects[pMonitor->numCommonSects] = gCommonSections.AddOneSection(buf, lines[i]); pMonitor->numCommonSects++; */ } else if (stricmp(lines[i], "HKR,,DPMS,,1") == 0) { pMonitor->CommonSects[pMonitor->numCommonSects] = gCommonSections.AddOneSection("DPMS", lines[i]); pMonitor->numCommonSects++; } else if (strnicmp(lines[i], "HKR,,MaxResolution,,\"", lstrlen("HKR,,MaxResolution,,\"")) == 0) { TCHAR buf[64]; LPSTR ptr; strcpy(buf, lines[i] + lstrlen("HKR,,MaxResolution,,\"")); ptr = strchr(buf, ','); ASSERT(ptr != NULL); *ptr = '\0'; pMonitor->CommonSects[pMonitor->numCommonSects] = gCommonSections.AddOneSection(buf, lines[i]); pMonitor->numCommonSects++; } ///////////////////////////////////////////////////////////////////////// // Something common in specific Manufacturers else if ((strnicmp(lines[i], "HKR,,LF,0,1", lstrlen("HKR,,LF,0,1")) == 0) || (strnicmp(lines[i], "HKR,,VE,0,1", lstrlen("HKR,,LF,0,1")) == 0)) { } else { sprintf(gszMsg, "Monitor %s/%s has unexpected AddReg Section %s", &pMonitor->ID[8], pMonitor->InstallSectionName, lines[i]); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); } } return TRUE; } LPSECTION CMonitorInf::SeekSection(LPCSTR sectionName) { for (UINT i = 0; i < numSections; i++) { if (stricmp(sections[i].name, sectionName) == 0) return §ions[i]; } return NULL; } VOID CMonitorInf::Pack(VOID) { for (int i = 0; i < ManufacturerArray.GetSize(); i++) { CManufacturer *pManufacturer = (CManufacturer*)ManufacturerArray[i]; if (pManufacturer->MonitorArray.GetSize() == 0) { delete pManufacturer; ManufacturerArray.RemoveAt(i); i--; } } } LPCOMMON_ALIAS CMonitorInf::LookupCommonAlias(LPCSTR lpAliasName, LPCOMMON_ALIAS AliasHead, UINT numAlias) { TCHAR name[64]; lstrcpy(name, lpAliasName+1); ASSERT(lpAliasName[0] == '%'); ASSERT(lpAliasName[lstrlen(name)] == '%'); name[lstrlen(name)-1] = '\0'; for (UINT i = 0; i < numAlias; i++) { if (stricmp(name, AliasHead[i].lpAlias) == 0) return &AliasHead[i]; } return NULL; } BOOL CMonitorInf::FillupAlias(VOID) { ///////////////////////////////////////////////////////////////////// // First read in all strings LPSECTION pSection = SeekSection("Strings"); if (pSection == NULL) { ASSERT(FALSE); return FALSE; } int numAlias = pSection->endLine - pSection->startLine; ASSERT(numAlias > 0); LPCOMMON_ALIAS pInfAlias = (LPCOMMON_ALIAS)malloc(numAlias * sizeof(COMMON_ALIAS)); if (pInfAlias == NULL) { ASSERT(FALSE); return FALSE; } LPCOMMON_ALIAS pAlias = pInfAlias; for (UINT i = pSection->startLine + 1; i <= pSection->endLine; i++, pAlias++) { if (TokenOneLine(lines[i], '=', m_tokens) != 2) { sprintf(gszMsg, "A wrong string line %s.", lines[i]); MessageBox(NULL, gszMsg, gszInputFileName, MB_OK); ASSERT(FALSE); free(pInfAlias); return FALSE; } pAlias->lpAlias = m_tokens[0]; pAlias->lpContents = m_tokens[1]; ASSERT(pAlias->lpContents[0] == '\"'); } ////////////////////////////////////////////////////////// // Go through Manufacturers and Monitors to fill up alias for (i = 0; i < (UINT)ManufacturerArray.GetSize(); i++) { CManufacturer *pManufacturer = (CManufacturer*)ManufacturerArray[i]; pAlias = LookupCommonAlias(pManufacturer->AliasName, pInfAlias, numAlias); if (pAlias == NULL) { ASSERT(FALSE); free(pInfAlias); return FALSE; } pAlias = gCommonAlias.AddOneAlias(pAlias->lpAlias, pAlias->lpContents); if (pAlias == NULL) { ASSERT(FALSE); free(pInfAlias); return FALSE; } pManufacturer->pAlias = pAlias; for (int j = 0; j < pManufacturer->MonitorArray.GetSize(); j++) { CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[j]; pAlias = LookupCommonAlias(pMonitor->AliasName, pInfAlias, numAlias); if (pAlias == NULL) { ASSERT(FALSE); free(pInfAlias); return FALSE; } pAlias = gCommonAlias.AddOneAlias(pAlias->lpAlias, pAlias->lpContents); if (pAlias == NULL) { ASSERT(FALSE); free(pInfAlias); return FALSE; } pMonitor->pAlias = pAlias; } } free(pInfAlias); return TRUE; }