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.

309 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. pnpids.c
  5. Abstract:
  6. Dumps out the PNP IDs of one or more INFs
  7. Author:
  8. Jim Schmidt (jimschm) 10-Jun-1999
  9. Revision History:
  10. <full name> (<alias>) <date> <comments>
  11. --*/
  12. #include "pch.h"
  13. HANDLE g_hHeap;
  14. HINSTANCE g_hInst;
  15. BOOL WINAPI MigUtil_Entry (HINSTANCE, DWORD, PVOID);
  16. BOOL
  17. pCallEntryPoints (
  18. DWORD Reason
  19. )
  20. {
  21. HINSTANCE Instance;
  22. //
  23. // Simulate DllMain
  24. //
  25. Instance = g_hInst;
  26. //
  27. // Initialize the common libs
  28. //
  29. if (!MigUtil_Entry (Instance, Reason, NULL)) {
  30. return FALSE;
  31. }
  32. return TRUE;
  33. }
  34. BOOL
  35. Init (
  36. VOID
  37. )
  38. {
  39. g_hHeap = GetProcessHeap();
  40. g_hInst = GetModuleHandle (NULL);
  41. return pCallEntryPoints (DLL_PROCESS_ATTACH);
  42. }
  43. VOID
  44. Terminate (
  45. VOID
  46. )
  47. {
  48. pCallEntryPoints (DLL_PROCESS_DETACH);
  49. }
  50. VOID
  51. HelpAndExit (
  52. VOID
  53. )
  54. {
  55. //
  56. // This routine is called whenever command line args are wrong
  57. //
  58. _ftprintf (
  59. stderr,
  60. TEXT("Command Line Syntax:\n\n")
  61. TEXT(" pnpids [directory|file]\n")
  62. TEXT("\nDescription:\n\n")
  63. TEXT(" PNPIDS.EXE lists the Plug-and-Play IDs found in an installer INF.\n")
  64. TEXT("\nArguments:\n\n")
  65. TEXT(" directory - OPTIONAL: Specifies a directory to process\n")
  66. TEXT(" file - OPTIONAL: Specifies a specific INF file to process\n\n")
  67. TEXT("If no arguments are specified, all INFs in the current directory are\n")
  68. TEXT("processed.\n")
  69. );
  70. exit (1);
  71. }
  72. BOOL
  73. pProcessInf (
  74. IN PCTSTR FileSpec
  75. )
  76. {
  77. HINF Inf;
  78. INFSTRUCT isMfg = INITINFSTRUCT_GROWBUFFER;
  79. INFSTRUCT isDev = INITINFSTRUCT_GROWBUFFER;
  80. PCTSTR Str;
  81. UINT u, v;
  82. UINT Devices;
  83. UINT Ids;
  84. Inf = InfOpenInfFile (FileSpec);
  85. if (Inf == INVALID_HANDLE_VALUE) {
  86. return FALSE;
  87. }
  88. if (InfFindFirstLine (Inf, "Manufacturer", NULL, &isMfg)) {
  89. do {
  90. Str = InfGetStringField (&isMfg, 0);
  91. if (!Str) {
  92. continue;
  93. }
  94. _tprintf (
  95. TEXT("[%s] Manufacturer: %s\n\n"),
  96. GetFileNameFromPath (FileSpec),
  97. Str
  98. );
  99. u = 1;
  100. Devices = 0;
  101. for (;;) {
  102. Str = InfGetStringField (&isMfg, u);
  103. u++;
  104. if (!Str) {
  105. break;
  106. }
  107. if (!*Str) {
  108. continue;
  109. }
  110. if (InfFindFirstLine (Inf, Str, NULL, &isDev)) {
  111. Ids = 0;
  112. do {
  113. Str = InfGetStringField (&isDev, 0);
  114. if (!Str) {
  115. continue;
  116. }
  117. _tprintf (TEXT(" %s:\n"), Str);
  118. Devices++;
  119. v = 2;
  120. for (;;) {
  121. Str = InfGetStringField (&isDev, v);
  122. v++;
  123. if (!Str) {
  124. break;
  125. }
  126. if (!*Str) {
  127. continue;
  128. }
  129. Ids++;
  130. _tprintf (TEXT(" %s\n"), Str);
  131. }
  132. } while (InfFindNextLine (&isDev));
  133. if (!Ids) {
  134. _tprintf (TEXT(" (no PNP IDs)\n"));
  135. }
  136. }
  137. }
  138. if (!Devices) {
  139. printf (" (no devices)\n\n");
  140. } else {
  141. printf ("\n %u device%s listed\n\n", Devices, Devices == 1 ? "" : "s");
  142. }
  143. } while (InfFindNextLine (&isMfg));
  144. }
  145. InfCleanUpInfStruct (&isMfg);
  146. InfCleanUpInfStruct (&isDev);
  147. return TRUE;
  148. }
  149. INT
  150. __cdecl
  151. _tmain (
  152. INT argc,
  153. PCTSTR argv[]
  154. )
  155. {
  156. INT i;
  157. PCTSTR FileArg = NULL;
  158. DWORD Attribs;
  159. FILE_ENUM e;
  160. UINT Processed = 0;
  161. PCTSTR Pattern = TEXT("*.INF");
  162. for (i = 1 ; i < argc ; i++) {
  163. if (argv[i][0] == TEXT('/') || argv[i][0] == TEXT('-')) {
  164. HelpAndExit();
  165. } else {
  166. //
  167. // Parse other args that don't require / or -
  168. //
  169. if (FileArg) {
  170. HelpAndExit();
  171. } else {
  172. FileArg = argv[i];
  173. }
  174. }
  175. }
  176. //
  177. // Begin processing
  178. //
  179. if (!Init()) {
  180. return 0;
  181. }
  182. if (!FileArg) {
  183. FileArg = TEXT(".");
  184. }
  185. if (_tcschr (FileArg, '*') || _tcschr (FileArg, '?')) {
  186. if (_tcschr (FileArg, TEXT('\\'))) {
  187. HelpAndExit();
  188. }
  189. Pattern = FileArg;
  190. Attribs = FILE_ATTRIBUTE_DIRECTORY;
  191. FileArg = TEXT(".");
  192. } else {
  193. Attribs = GetFileAttributes (FileArg);
  194. if (Attribs == INVALID_ATTRIBUTES) {
  195. _ftprintf (stderr, TEXT("%s is not valid.\n\n"), FileArg);
  196. HelpAndExit();
  197. }
  198. }
  199. if (Attribs & FILE_ATTRIBUTE_DIRECTORY) {
  200. if (EnumFirstFile (&e, FileArg, Pattern)) {
  201. do {
  202. if (pProcessInf (e.FullPath)) {
  203. Processed++;
  204. }
  205. } while (EnumNextFile (&e));
  206. }
  207. } else {
  208. if (pProcessInf (FileArg)) {
  209. Processed++;
  210. }
  211. }
  212. _ftprintf (
  213. stderr,
  214. TEXT("%u file%s processed.\n"),
  215. Processed,
  216. Processed == 1 ? TEXT("") : TEXT("s")
  217. );
  218. //
  219. // End of processing
  220. //
  221. Terminate();
  222. return 0;
  223. }