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.

546 lines
17 KiB

  1. #include "stdafx.h"
  2. #include "mon.h"
  3. const TCHAR GenericMannufacturerSection[] =
  4. "[Generic]\n\
  5. %Unknown.DeviceDesc%=Unknown.Install,Monitor\\Default_Monitor ; for auto-install\n\
  6. %Unknown.DeviceDesc%=Unknown.Install ; for pick list\n\
  7. %*PNP09FF.DeviceDesc%=VESADDC.Install,*PNP09FF\n\
  8. \n\
  9. %Laptop640.DeviceDesc%=Laptop640.Install,Monitor\\MS_0001\n\
  10. %Laptop800.DeviceDesc%=Laptop800.Install,Monitor\\MS_0002\n\
  11. %Laptop1024.DeviceDesc%=Laptop1024.Install,Monitor\\MS_0003\n\
  12. %Laptop1152.DeviceDesc%=Laptop1152.Install,Monitor\\MS_0004\n\
  13. %Laptop1280.DeviceDesc%=Laptop1280.Install,Monitor\\MS_0005\n\
  14. %Laptop1600.DeviceDesc%=Laptop1600.Install,Monitor\\MS_0006\n\
  15. \n\
  16. %TVGen.DeviceDesc%=640.Install,Monitor\\PNP09FE\n\
  17. %TVGen.DeviceDesc%=640.Install,Monitor\\*PNP09FE\n\
  18. \n\
  19. %640.DeviceDesc%=640.Install,Monitor\\MS_0640\n\
  20. %800.DeviceDesc%=800.Install,Monitor\\MS_0800\n\
  21. %1024.DeviceDesc%=1024.Install,Monitor\\MS_1024\n\
  22. %1280.DeviceDesc%=1280.Install,Monitor\\MS_1280\n\
  23. %1600.DeviceDesc%=1600.Install,Monitor\\MS_1600\n\n";
  24. const TCHAR GenericInstallSection[] =
  25. "; -------------- Generic types\n\
  26. [Unknown.Install]\n\
  27. DelReg=DCR\n\
  28. AddReg=Unknown.AddReg\n\
  29. \n\
  30. [VESADDC.Install]\n\
  31. DelReg=DCR\n\
  32. AddReg=VESADDC.AddReg, 1600, DPMS\n\
  33. \n\
  34. [Laptop640.Install]\n\
  35. DelReg=DCR\n\
  36. AddReg=640VESA60, DPMS\n\
  37. \n\
  38. [Laptop800.Install]\n\
  39. DelReg=DCR\n\
  40. AddReg=800VESA60, DPMS\n\
  41. \n\
  42. [Laptop1024.Install]\n\
  43. DelReg=DCR\n\
  44. AddReg=1024VESA60, DPMS\n\
  45. \n\
  46. [Laptop1152.Install]\n\
  47. DelReg=DCR\n\
  48. AddReg=1152VESA60, DPMS\n\
  49. \n\
  50. [Laptop1280.Install]\n\
  51. DelReg=DCR\n\
  52. AddReg=1280VESA60, DPMS\n\
  53. \n\
  54. [Laptop1600.Install]\n\
  55. DelReg=DCR\n\
  56. AddReg=1600VESA60, DPMS\n\
  57. \n\
  58. [640.Install]\n\
  59. DelReg=DCR\n\
  60. AddReg=640\n\
  61. \n\
  62. [800.Install]\n\
  63. DelReg=DCR\n\
  64. AddReg=800\n\
  65. \n\
  66. [1024.Install]\n\
  67. DelReg=DCR\n\
  68. AddReg=1024\n\
  69. \n\
  70. [1280.Install]\n\
  71. DelReg=DCR\n\
  72. AddReg=1280\n\
  73. \n\
  74. [1600.Install]\n\
  75. DelReg=DCR\n\
  76. AddReg=1600\n\n";
  77. const TCHAR GenericAddRegSection[] =
  78. "; -------------- Generic types\n\
  79. [Unknown.AddReg]\n\
  80. HKR,\"MODES\\640,480\"\n\
  81. \n\
  82. [VESADDC.AddReg]\n\
  83. HKR,\"MODES\\1600,1200\"\n\
  84. \n\
  85. [VGA.AddReg]\n\
  86. HKR,\"MODES\\640,480\",Mode1,,\"31.5,50.0-70.0,-,-\"\n\
  87. \n\
  88. [640VESA60]\n\
  89. HKR,\"MODES\\640,480\",Mode1,,\"60.0,50.0,-,-\"\n\
  90. HKR,,PreferredMode,,\"640,480,60\"\n\
  91. \n\
  92. [800VESA60]\n\
  93. HKR,\"MODES\\640,480\",Mode1,,\"60.0,50.0,-,-\"\n\
  94. HKR,\"MODES\\800,600\",Mode1,,\"60.0,60.0,+,+\"\n\
  95. HKR,,PreferredMode,,\"800,600,60\"\n\
  96. \n\
  97. [1024VESA60]\n\
  98. HKR,\"MODES\\640,480\",Mode1,,\"60.0,50.0,-,-\"\n\
  99. HKR,\"MODES\\1024,768\",Mode1,,\"60.0,60.0,+,+\"\n\
  100. HKR,,PreferredMode,,\"1024,768,60\"\n\
  101. \n\
  102. [1152VESA60]\n\
  103. HKR,\"MODES\\640,480\",Mode1,,\"60.0,50.0,-,-\"\n\
  104. HKR,\"MODES\\1152,864\",Mode1,,\"60.0,60.0,+,+\"\n\
  105. HKR,,PreferredMode,,\"1152,864,60\"\n\
  106. \n\
  107. [1280VESA60]\n\
  108. HKR,\"MODES\\640,480\",Mode1,,\"60.0,50.0,-,-\"\n\
  109. HKR,\"MODES\\1280,1024\",Mode1,,\"48.0,65.0,+,+\"\n\
  110. HKR,,PreferredMode,,\"1280,1024,60\"\n\
  111. \n\
  112. [1600VESA60]\n\
  113. HKR,\"MODES\\640,480\",Mode1,,\"60.0,60.0,-,-\"\n\
  114. HKR,\"MODES\\1600,1200\",Mode1,,\"48.0,75.0,+,+\"\n\
  115. HKR,,PreferredMode,,\"1600,1200,60\"\n\n";
  116. const TCHAR GenericStrings[] =
  117. "MonitorClassName=\"Monitors\"\n\
  118. MS=\"Microsoft\"\n\
  119. \n\
  120. Generic=\"(Standard monitor types)\"\n\
  121. Unknown.DeviceDesc=\"Default Monitor\"\n\
  122. \n\
  123. *PNP09FF.DeviceDesc = \"Plug and Play Monitor\"\n\
  124. \n\
  125. Laptop640.DeviceDesc = \"Digital Flat Panel (640x480)\"\n\
  126. Laptop800.DeviceDesc = \"Digital Flat Panel (800x600)\"\n\
  127. Laptop1024.DeviceDesc =\"Digital Flat Panel (1024x768)\"\n\
  128. Laptop1152.DeviceDesc =\"Digital Flat Panel (1152x864)\"\n\
  129. Laptop1280.DeviceDesc =\"Digital Flat Panel (1280x1024)\"\n\
  130. Laptop1600.DeviceDesc =\"Digital Flat Panel (1600x1200)\"\n\
  131. \n\
  132. TVGen.DeviceDesc =\"Generic Television\"\n\
  133. \n\
  134. 640.DeviceDesc = \"Standard VGA 640x480\"\n\
  135. 800.DeviceDesc = \"Super VGA 800x600\"\n\
  136. 1024.DeviceDesc = \"Super VGA 1024x768\"\n\
  137. 1280.DeviceDesc = \"Super VGA 1280x1024\"\n\
  138. 1600.DeviceDesc = \"Super VGA 1600x1200\"\n\n";
  139. VOID CSumInf::DumpMonitorInf(LPCSTR DumpFilePath, int sizeLimit)
  140. {
  141. TCHAR DumpFileName[256];
  142. sprintf(DumpFileName, "%s\\tmp.txt", DumpFilePath);
  143. ASSERT(m_ManufacturerArray.GetSize());
  144. if (sizeLimit == 0xFFFFFFFF)
  145. {
  146. sprintf(DumpFileName, "%s\\MONITOR.INF", DumpFilePath);
  147. DumpManufacturers(DumpFileName, 0, m_ManufacturerArray.GetSize(), 1);
  148. return;
  149. }
  150. int fileBreaks[64], numFileBreaks = 0, fileSize = 0;
  151. int start = 0, end = 0;
  152. // 0
  153. // 0 1 2
  154. // 0 1 2 | 3 4 | 5
  155. // e e e=6
  156. while (1)
  157. {
  158. end++;
  159. if (end >= m_ManufacturerArray.GetSize())
  160. {
  161. fileBreaks[numFileBreaks++] = end;
  162. break;
  163. }
  164. fileSize = DumpManufacturers(DumpFileName, start, end-start, (start == 0) ? 6 : 0);
  165. if (fileSize >= sizeLimit)
  166. {
  167. fileBreaks[numFileBreaks++] = end;
  168. start = end;
  169. fileSize = 0;
  170. }
  171. }
  172. sprintf(DumpFileName, "%s\\MONITOR.INF", DumpFilePath);
  173. DumpManufacturers(DumpFileName, 0, fileBreaks[0], numFileBreaks);
  174. for (int i = 0; i < (numFileBreaks-1); i++)
  175. {
  176. sprintf(DumpFileName, "%s\\MONITOR%d.INF", DumpFilePath, i+2);
  177. DumpManufacturers(DumpFileName, fileBreaks[i], fileBreaks[i+1]-fileBreaks[i], 0);
  178. }
  179. }
  180. int CSumInf::DumpManufacturers(LPCSTR DumpFileName, int start, int num, int numInfs)
  181. {
  182. FILE *fpOut = fopen(DumpFileName, "w");
  183. LPCSTR lpFileName = strrchr(DumpFileName, '\\');
  184. ASSERT(lpFileName != NULL);
  185. lpFileName++;
  186. if (fpOut == NULL)
  187. return 0;
  188. fprintf(fpOut, "; %s\n;\n", lpFileName);
  189. DumpCommonHeader(fpOut, numInfs);
  190. int end = min(start+num, m_ManufacturerArray.GetSize());
  191. for (int i = start; i < end; i++)
  192. {
  193. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  194. fprintf(fpOut, "%s=%s\n", pManufacturer->AliasName, pManufacturer->name);
  195. }
  196. fprintf(fpOut, "\n\n;-------------------------------------------------\n");
  197. fprintf(fpOut, "; Manufacturer Sections\n\n");
  198. if (numInfs)
  199. {
  200. fprintf(fpOut, "%s", GenericMannufacturerSection);
  201. }
  202. for (i = start; i < end; i++)
  203. {
  204. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  205. DumpManufactureSection(fpOut, pManufacturer);
  206. }
  207. fprintf(fpOut, "\n;-------------------------------------------------\n");
  208. fprintf(fpOut, "; Install sections\n\n");
  209. if (numInfs)
  210. {
  211. fprintf(fpOut, "%s", GenericInstallSection);
  212. }
  213. for (i = start; i < end; i++)
  214. {
  215. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  216. DumpInstallSection(fpOut, pManufacturer);
  217. }
  218. fprintf(fpOut, "\n;-------------------------------------------------\n");
  219. fprintf(fpOut, "; Common AddReg sections\n");
  220. DumpCommonAddRegSection(fpOut, start, end);
  221. fprintf(fpOut, "\n;-------------------------------------------------\n");
  222. fprintf(fpOut, "; Model AddReg sections\n\n");
  223. if (numInfs)
  224. {
  225. fprintf(fpOut, "%s", GenericAddRegSection);
  226. }
  227. for (i = start; i < end; i++)
  228. {
  229. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  230. DumpAddRegSection(fpOut, pManufacturer);
  231. }
  232. fprintf(fpOut, "\n;-------------------------------------------------\n");
  233. fprintf(fpOut, "; User visible strings\n\n");
  234. fprintf(fpOut, "[Strings]\n");
  235. if (numInfs)
  236. {
  237. fprintf(fpOut, "%s", GenericStrings);
  238. }
  239. else
  240. fprintf(fpOut, "MS=\"Microsoft\"\n\n");
  241. DumpCommonStringSection(fpOut, start, end);
  242. fpos_t fileSize = 0;
  243. ASSERT( fgetpos(fpOut, &fileSize) == 0 );
  244. fclose(fpOut);
  245. return (int)fileSize;
  246. }
  247. VOID CSumInf::DumpManufactureSection(FILE *fp, CManufacturer *pManufacturer)
  248. {
  249. fprintf(fp, "[%s]\n", pManufacturer->name);
  250. for (int i = 0; i < pManufacturer->MonitorArray.GetSize(); i++)
  251. {
  252. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[i];
  253. fprintf(fp, "%s=%s, %s\n",
  254. pMonitor->AliasName,
  255. pMonitor->InstallSectionName,
  256. pMonitor->ID);
  257. }
  258. fprintf(fp, "\n");
  259. }
  260. VOID CSumInf::DumpInstallSection(FILE *fp, CManufacturer *pManufacturer)
  261. {
  262. fprintf(fp, "; -------------- %s\n", pManufacturer->name);
  263. for (int i = 0; i < pManufacturer->MonitorArray.GetSize(); i++)
  264. {
  265. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[i];
  266. /////////////////////////////////////////////////////////////
  267. // If this Monitor has duplicated section, ignore it
  268. if (pMonitor->bDupInstSection)
  269. {
  270. continue;
  271. }
  272. fprintf(fp, "[%s]\n", pMonitor->InstallSectionName);
  273. fprintf(fp, "DelReg=DCR\n");
  274. fprintf(fp, "AddReg=%s", pMonitor->AddRegSectionName);
  275. for (int j = 0; j < pMonitor->numCommonSects; j++)
  276. fprintf(fp, ", %s", pMonitor->CommonSects[j]->sectName);
  277. fprintf(fp, "\n\n");
  278. }
  279. }
  280. VOID CSumInf::DumpCommonAddRegSection(FILE *fp, int start, int end)
  281. {
  282. fprintf(fp, "\n[DCR]\n");
  283. fprintf(fp, "HKR,MODES\n");
  284. fprintf(fp, "HKR,,MaxResolution\n");
  285. fprintf(fp, "HKR,,DPMS\n");
  286. fprintf(fp, "HKR,,ICMProfile\n\n");
  287. for (int i = 0; i < gCommonSections.GetSize(); i++)
  288. {
  289. LPCOMMON_SECTION pSection = gCommonSections.GetAt(i);
  290. pSection->refCount = 0;
  291. }
  292. for (i = start; i < end; i++)
  293. {
  294. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  295. for (int j = 0; j < pManufacturer->MonitorArray.GetSize(); j++)
  296. {
  297. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[j];
  298. for (int k = 0; k < pMonitor->numCommonSects; k++)
  299. pMonitor->CommonSects[k]->refCount++;
  300. }
  301. }
  302. ////////////////////////////////////////////////////////
  303. // For generic common sections
  304. if (start == 0)
  305. {
  306. for (int i = 0; i < gCommonSections.GetSize(); i++)
  307. {
  308. LPCOMMON_SECTION pSection = gCommonSections.GetAt(i);
  309. if (stricmp(pSection->sectName, "DPMS") == 0 ||
  310. stricmp(pSection->sectName, "1600") == 0 ||
  311. stricmp(pSection->sectName, "640") == 0 ||
  312. stricmp(pSection->sectName, "800") == 0 ||
  313. stricmp(pSection->sectName, "1024") == 0 ||
  314. stricmp(pSection->sectName, "1280") == 0)
  315. pSection->refCount++;
  316. }
  317. }
  318. for (i = 0; i < gCommonSections.GetSize(); i++)
  319. {
  320. LPCOMMON_SECTION pSection = gCommonSections.GetAt(i);
  321. if (pSection->refCount == 0)
  322. continue;
  323. fprintf(fp, "[%s]\n", pSection->sectName);
  324. fprintf(fp, "%s\n\n", pSection->contents);
  325. }
  326. }
  327. VOID CSumInf::DumpAddRegSection(FILE *fp, CManufacturer *pManufacturer)
  328. {
  329. fprintf(fp, "; -------------- %s\n", pManufacturer->name);
  330. for (int i = 0; i < pManufacturer->MonitorArray.GetSize(); i++)
  331. {
  332. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[i];
  333. /////////////////////////////////////////////////////////////
  334. // If this Monitor has duplicated section, ignore it
  335. if (pMonitor->bDupInstSection)
  336. {
  337. continue;
  338. }
  339. ASSERT(lstrlen(pMonitor->AddRegSectionBuf) != 0);
  340. fprintf(fp, "[%s]\n", pMonitor->AddRegSectionName);
  341. fprintf(fp, "%s\n", pMonitor->AddRegSectionBuf);
  342. }
  343. }
  344. VOID CSumInf::DumpCommonStringSection(FILE *fp, int start, int end)
  345. {
  346. LPCOMMON_ALIAS pAlias;
  347. for (int i = 0; i < gCommonAlias.GetSize(); i++)
  348. {
  349. pAlias = gCommonAlias.GetAt(i);
  350. pAlias->refCount = 0;
  351. }
  352. ///////////////////////////////////////////
  353. // Calculate RefCount
  354. for (i = start; i < end; i++)
  355. {
  356. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  357. pAlias = pManufacturer->pAlias;
  358. ASSERT(pAlias != NULL);
  359. pAlias->refCount++;
  360. for (int j = 0; j < pManufacturer->MonitorArray.GetSize(); j++)
  361. {
  362. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[j];
  363. pAlias = pMonitor->pAlias;
  364. ASSERT(pAlias != NULL);
  365. pAlias->refCount++;
  366. }
  367. }
  368. ///////////////////////////////////////////
  369. // Actual dump
  370. for (i = start; i < end; i++)
  371. {
  372. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  373. pAlias = pManufacturer->pAlias;
  374. ASSERT(pAlias != NULL);
  375. if (pAlias->refCount == 1)
  376. {
  377. fprintf(fp, "%s=%s\n", pAlias->lpAlias, pAlias->lpContents);
  378. }
  379. else
  380. {
  381. pAlias->refCount--;
  382. }
  383. }
  384. fprintf(fp, "\n");
  385. for (i = start; i < end; i++)
  386. {
  387. CManufacturer *pManufacturer = (CManufacturer*)m_ManufacturerArray[i];
  388. for (int j = 0; j < pManufacturer->MonitorArray.GetSize(); j++)
  389. {
  390. CMonitor *pMonitor = (CMonitor*)pManufacturer->MonitorArray[j];
  391. pAlias = pMonitor->pAlias;
  392. ASSERT(pAlias != NULL);
  393. if (pAlias->refCount == 1)
  394. {
  395. fprintf(fp, "%s=%s\n", pAlias->lpAlias, pAlias->lpContents);
  396. }
  397. else
  398. {
  399. pAlias->refCount--;
  400. }
  401. }
  402. fprintf(fp, "\n");
  403. }
  404. }
  405. VOID CSumInf::DumpCommonHeader(FILE *fp, int numInfs)
  406. {
  407. if (numInfs == 0)
  408. {
  409. fprintf(fp, "; This is a Setup information file for monitors\n");
  410. fprintf(fp, "; supported in the Windows 2000 product.\n;\n");
  411. fprintf(fp, "; Copyright (c) 2000-2001, Microsoft Corporation\n\n");
  412. fprintf(fp, "[VERSION]\n");
  413. fprintf(fp, "Signature=\"$CHICAGO$\"\n");
  414. fprintf(fp, "Class=Monitor\n");
  415. fprintf(fp, "ClassGUID={4d36e96e-e325-11ce-bfc1-08002be10318}\n");
  416. fprintf(fp, "Provider=%%MS%%\n");
  417. fprintf(fp, "DriverVer=11/01/2000\n\n\n");
  418. fprintf(fp, ";-------------------------------------------------\n");
  419. fprintf(fp, "; Manufacturers\n\n");
  420. fprintf(fp, "[Manufacturer]\n");
  421. }
  422. else
  423. {
  424. fprintf(fp, "; This is Setup information file for monitors \n");
  425. fprintf(fp, ";\n");
  426. fprintf(fp, "; Copyright (c) 2000-2001, Microsoft Corporation\n\n");
  427. fprintf(fp, "[version]\n");
  428. fprintf(fp, "LayoutFile=layout.inf, layout1.inf\n");
  429. fprintf(fp, "signature=\"$CHICAGO$\"\n");
  430. fprintf(fp, "Class=Monitor\n");
  431. fprintf(fp, "ClassGUID={4d36e96e-e325-11ce-bfc1-08002be10318}\n");
  432. fprintf(fp, "Provider=%%MS%%\n");
  433. fprintf(fp, "SetupClass=BASE\n");
  434. fprintf(fp, "DriverVer=11/01/2000\n\n");
  435. fprintf(fp, "[DestinationDirs]\n");
  436. fprintf(fp, "DefaultDestDir = 11 ; LDID_SYS\n");
  437. fprintf(fp, "monitor.infs.copy = 17 ; LDID_INF\n\n\n");
  438. fprintf(fp, "; Base Install Sections\n");
  439. fprintf(fp, ";-------------------------------------------------\n");
  440. fprintf(fp, "[BaseWinOptions]\n");
  441. fprintf(fp, "MonitorBase\n\n");
  442. fprintf(fp, "[MonitorBase]\n");
  443. fprintf(fp, "CopyFiles=monitor.infs.copy\n");
  444. fprintf(fp, "[monitor.infs.copy]\n");
  445. fprintf(fp, "monitor.inf\n");
  446. for (int i = 1; i < numInfs; i++)
  447. {
  448. fprintf(fp, "monitor%d.inf\n", i+1);
  449. }
  450. fprintf(fp, "\n[SysCfgClasses]\n");
  451. fprintf(fp, "Monitor, %%Unknown.DeviceDesc%%,MONITOR,4,%%MonitorClassName%% ; Default to \"Unknown Monitor\"\n\n\n");
  452. fprintf(fp, "; Install class \"Monitor\"\n");
  453. fprintf(fp, ";-------------------------------------------------\n");
  454. fprintf(fp, "[ClassInstall]\n");
  455. fprintf(fp, "AddReg=ClassAddReg\n");
  456. fprintf(fp, "[ClassAddReg]\n");
  457. fprintf(fp, "HKR,,,,%%MonitorClassName%%\n");
  458. fprintf(fp, "HKR,,Installer,,\"SetupX.Dll, Monitor_ClassInstaller\"\n");
  459. fprintf(fp, "HKR,,Icon,,\"-1\"\n\n");
  460. fprintf(fp, "[ClassDelReg]\n\n\n");
  461. fprintf(fp, "[ClassInstall32.NT]\n");
  462. fprintf(fp, "AddReg=monitor_class_addreg\n");
  463. fprintf(fp, "[monitor_class_addreg]\n");
  464. fprintf(fp, "HKR,,,,%%MonitorClassName%%\n");
  465. fprintf(fp, "HKR,,Installer32,,\"Desk.Cpl,MonitorClassInstaller\"\n");
  466. fprintf(fp, "HKR,,Icon,,\"-1\"\n");
  467. fprintf(fp, "HKR,,NoInstallClass,,\"1\"\n");
  468. fprintf(fp, "HKR,,TroubleShooter-0,,\"hcp://help/tshoot/tsdisp.htm\"\n");
  469. fprintf(fp, "HKR,,SilentInstall,,1\n\n");
  470. fprintf(fp, "; Monitors to hide from pick list\n");
  471. fprintf(fp, ";-------------------------------------------------\n");
  472. fprintf(fp, "[ControlFlags]\n");
  473. fprintf(fp, "ExcludeFromSelect=Monitor\\Default_Monitor\n\n");
  474. fprintf(fp, ";-------------------------------------------------\n");
  475. fprintf(fp, "; Manufacturers\n\n");
  476. fprintf(fp, "[Manufacturer]\n");
  477. fprintf(fp, "%%Generic%%=Generic\n");
  478. }
  479. }