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.

461 lines
13 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. infsdisk.c
  5. Abstract:
  6. Externally exposed INF routines for source disk descriptor manipulation.
  7. Author:
  8. Ted Miller (tedm) 9-Feb-1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. // Locations of various fields in the [SourceDisksNames] section
  15. // of an inf
  16. //
  17. #define DISKNAMESECT_DESCRIPTION 1
  18. #define DISKNAMESECT_TAGFILE 2 // cabinet name in win95
  19. #define DISKNAMESECT_OEM 3 // unused, indicates oem disk in win95
  20. #define DISKNAMESECT_PATH 4
  21. #define DISKNAMESECT_FLAGS 5 // indicates extra tags
  22. #define DISKNAMESECT_TAGFILE2 6 // real tagfile if DISKNAMESECT_TAGFILE is really a cabfile
  23. #ifdef UNICODE
  24. //
  25. // ANSI version
  26. //
  27. BOOL
  28. SetupGetSourceInfoA(
  29. IN HINF InfHandle,
  30. IN UINT SourceId,
  31. IN UINT InfoDesired,
  32. OUT PSTR ReturnBuffer, OPTIONAL
  33. IN DWORD ReturnBufferSize,
  34. OUT PDWORD RequiredSize OPTIONAL
  35. )
  36. {
  37. DWORD rc;
  38. BOOL b;
  39. PWCHAR buffer;
  40. DWORD requiredsize;
  41. PCSTR ansi;
  42. buffer = MyMalloc(MAX_INF_STRING_LENGTH);
  43. if (buffer) {
  44. b = pSetupGetSourceInfo(
  45. InfHandle,
  46. NULL,
  47. SourceId,
  48. NULL,
  49. InfoDesired,
  50. buffer,
  51. MAX_INF_STRING_LENGTH,
  52. &requiredsize
  53. );
  54. rc = GetLastError();
  55. if(b) {
  56. rc = NO_ERROR;
  57. if(ansi = pSetupUnicodeToAnsi(buffer)) {
  58. requiredsize = lstrlenA(ansi)+1;
  59. if(RequiredSize) {
  60. try {
  61. *RequiredSize = requiredsize;
  62. } except(EXCEPTION_EXECUTE_HANDLER) {
  63. rc = ERROR_INVALID_PARAMETER;
  64. b = FALSE;
  65. }
  66. }
  67. if((rc == NO_ERROR) && ReturnBuffer) {
  68. if(!lstrcpynA(ReturnBuffer,ansi,ReturnBufferSize)) {
  69. //
  70. // ReturnBuffer invalid
  71. //
  72. rc = ERROR_INVALID_PARAMETER;
  73. b = FALSE;
  74. }
  75. }
  76. MyFree(ansi);
  77. } else {
  78. rc = ERROR_NOT_ENOUGH_MEMORY;
  79. b = FALSE;
  80. }
  81. }
  82. MyFree(buffer);
  83. } else {
  84. rc = ERROR_NOT_ENOUGH_MEMORY;
  85. b = FALSE;
  86. }
  87. SetLastError(rc);
  88. return(b);
  89. }
  90. #else
  91. //
  92. // Unicode stub
  93. //
  94. BOOL
  95. SetupGetSourceInfoW(
  96. IN HINF InfHandle,
  97. IN UINT SourceId,
  98. IN UINT InfoDesired,
  99. OUT PWSTR ReturnBuffer, OPTIONAL
  100. IN DWORD ReturnBufferSize,
  101. OUT PDWORD RequiredSize OPTIONAL
  102. )
  103. {
  104. UNREFERENCED_PARAMETER(InfHandle);
  105. UNREFERENCED_PARAMETER(SourceId);
  106. UNREFERENCED_PARAMETER(InfoDesired);
  107. UNREFERENCED_PARAMETER(ReturnBuffer);
  108. UNREFERENCED_PARAMETER(ReturnBufferSize);
  109. UNREFERENCED_PARAMETER(RequiredSize);
  110. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  111. return(FALSE);
  112. }
  113. #endif
  114. BOOL
  115. SetupGetSourceInfo(
  116. IN HINF InfHandle,
  117. IN UINT SourceId,
  118. IN UINT InfoDesired,
  119. OUT PTSTR ReturnBuffer, OPTIONAL
  120. IN DWORD ReturnBufferSize,
  121. OUT PDWORD RequiredSize OPTIONAL
  122. )
  123. //
  124. // Native version
  125. //
  126. {
  127. return pSetupGetSourceInfo(InfHandle,
  128. NULL,
  129. SourceId,
  130. NULL,
  131. InfoDesired,
  132. ReturnBuffer,
  133. ReturnBufferSize,
  134. RequiredSize
  135. );
  136. }
  137. BOOL
  138. pSetupGetSourceInfo(
  139. IN HINF InfHandle, OPTIONAL
  140. IN PINFCONTEXT LayoutLineContext, OPTIONAL
  141. IN UINT SourceId,
  142. IN PSP_ALTPLATFORM_INFO_V2 AltPlatformInfo, OPTIONAL
  143. IN UINT InfoDesired,
  144. OUT PTSTR ReturnBuffer, OPTIONAL
  145. IN DWORD ReturnBufferSize,
  146. OUT PDWORD RequiredSize OPTIONAL
  147. )
  148. /*++
  149. Routine Description:
  150. Get information from SourceDisksNames
  151. If InfHandle specified instead of LayoutLineContext
  152. and the ID is specified in more than one INF
  153. then the wrong information *MAY* be returned.
  154. This effects callers of SetupGetSourceInfo
  155. we need a SetupGetSourceInfoEx post 5.0
  156. Arguments:
  157. InfHandle - required if LayoutLineContext is not provided, else specifies a layout inf
  158. SourceId - numerical source ID, used as search key in SourceDisksNames section
  159. AltPlatformInfo - optionally, supplies alternate platform information used
  160. in decorating the [SourceDisksNames] section.
  161. InfoDesired -
  162. SRCINFO_PATH
  163. SRCINFO_TAGFILE
  164. SRCINFO_DESCRIPTION
  165. SRCINFO_FLAGS
  166. ReturnBuffer - buffer for returned string
  167. ReturnBufferSize - size of buffer
  168. RequiredSize - size buffer needs to be if ReturnBufferSize too small
  169. LayoutLineContext - if specified, used to determine correct INF to use if SourceID's conflict
  170. Return Value:
  171. Boolean value indicating outcome. If FALSE, GetLastError() returns
  172. extended error information.
  173. ReturnBuffer filled out with string
  174. RequiredSize filled out with required size of buffer to hold string
  175. --*/
  176. {
  177. PCTSTR PlatformName;
  178. UINT ValueIndex;
  179. BOOL Mandatory;
  180. BOOL IsPath;
  181. INFCONTEXT InfContext;
  182. INFCONTEXT SelectedInfContext;
  183. int SelectedRank;
  184. TCHAR SourceIdString[24];
  185. PCTSTR Value;
  186. BOOL b;
  187. UINT Length;
  188. TCHAR MediaListSectionName[64];
  189. HINF hInfPreferred = (HINF)(-1);
  190. try {
  191. if ((LayoutLineContext != NULL) && (LayoutLineContext != (PINFCONTEXT)(-1))) {
  192. hInfPreferred = (HINF)LayoutLineContext->CurrentInf;
  193. }
  194. } except(EXCEPTION_EXECUTE_HANDLER) {
  195. hInfPreferred = (HINF)(-1);
  196. }
  197. //
  198. // Determine the index of the value that gives the caller the info he wants.
  199. //
  200. switch(InfoDesired) {
  201. case SRCINFO_PATH:
  202. ValueIndex = DISKNAMESECT_PATH;
  203. Mandatory = FALSE;
  204. IsPath = TRUE;
  205. break;
  206. case SRCINFO_TAGFILE:
  207. ValueIndex = DISKNAMESECT_TAGFILE;
  208. Mandatory = FALSE;
  209. IsPath = TRUE;
  210. break;
  211. case SRCINFO_DESCRIPTION:
  212. ValueIndex = DISKNAMESECT_DESCRIPTION;
  213. Mandatory = TRUE;
  214. IsPath = FALSE;
  215. break;
  216. case SRCINFO_FLAGS:
  217. ValueIndex = DISKNAMESECT_FLAGS;
  218. Mandatory = FALSE;
  219. IsPath = FALSE;
  220. break;
  221. case SRCINFO_TAGFILE2:
  222. ValueIndex = DISKNAMESECT_TAGFILE2;
  223. Mandatory = FALSE;
  224. IsPath = TRUE;
  225. break;
  226. default:
  227. SetLastError(ERROR_INVALID_PARAMETER);
  228. return(FALSE);
  229. }
  230. wsprintf(SourceIdString,TEXT("%d"),SourceId);
  231. if(AltPlatformInfo) {
  232. switch(AltPlatformInfo->ProcessorArchitecture) {
  233. case PROCESSOR_ARCHITECTURE_INTEL :
  234. PlatformName = pszX86SrcDiskSuffix;
  235. break;
  236. case PROCESSOR_ARCHITECTURE_ALPHA :
  237. PlatformName = pszAlphaSrcDiskSuffix;
  238. break;
  239. case PROCESSOR_ARCHITECTURE_IA64 :
  240. PlatformName = pszIa64SrcDiskSuffix;
  241. break;
  242. case PROCESSOR_ARCHITECTURE_ALPHA64 :
  243. PlatformName = pszAxp64SrcDiskSuffix;
  244. break;
  245. case PROCESSOR_ARCHITECTURE_AMD64 :
  246. PlatformName = pszAmd64SrcDiskSuffix;
  247. break;
  248. default :
  249. //
  250. // unknown/unsupported processor architecture.
  251. //
  252. MYASSERT((AltPlatformInfo->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) ||
  253. (AltPlatformInfo->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA) ||
  254. (AltPlatformInfo->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) ||
  255. (AltPlatformInfo->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) ||
  256. (AltPlatformInfo->ProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
  257. );
  258. SetLastError(ERROR_INVALID_PARAMETER);
  259. return(FALSE);
  260. }
  261. } else {
  262. PlatformName = pszPlatformSrcDiskSuffix;
  263. }
  264. _sntprintf(
  265. MediaListSectionName,
  266. sizeof(MediaListSectionName)/sizeof(MediaListSectionName[0]),
  267. TEXT("%s.%s"),
  268. pszSourceDisksNames,
  269. PlatformName
  270. );
  271. //
  272. // we will prefer
  273. // (1) an entry in hInfPreferred (Rank 11/12 decorated over undecorated)
  274. // (2) an entry linked to hInfPreferred (Rank 21/22 decorated over undecorated)
  275. // (3) an entry in hInfHandle (Rank 31/32 decorated over undecorated)
  276. // (4) an entry linked to InfHandle (Rank 41/42 decorated over undecorated)
  277. //
  278. SelectedRank = 100; // 11-42 as above
  279. if ((hInfPreferred != NULL) && (hInfPreferred != (HINF)(-1))) {
  280. //
  281. // see if we can find the SourceIdString in the INF that we found the section in
  282. //
  283. // rank 11 or 21 (decorated) - always try
  284. //
  285. if(SetupFindFirstLine(hInfPreferred,MediaListSectionName,SourceIdString,&InfContext)) {
  286. if (InfContext.Inf == InfContext.CurrentInf) {
  287. SelectedRank = 11;
  288. SelectedInfContext = InfContext;
  289. } else {
  290. SelectedRank = 21;
  291. SelectedInfContext = InfContext;
  292. }
  293. }
  294. if (SelectedRank > 12) {
  295. //
  296. // rank 12 or 22 (undecorated) only try if we haven't got anything better than 12
  297. //
  298. if(SetupFindFirstLine(hInfPreferred,pszSourceDisksNames,SourceIdString,&InfContext)) {
  299. if (InfContext.Inf == InfContext.CurrentInf) {
  300. SelectedRank = 12;
  301. SelectedInfContext = InfContext;
  302. } else if (SelectedRank > 22) {
  303. SelectedRank = 22;
  304. SelectedInfContext = InfContext;
  305. }
  306. }
  307. }
  308. }
  309. if ((InfHandle != NULL) && (InfHandle != (HINF)(-1)) && (SelectedRank > 31)) {
  310. //
  311. // see if we can find the SourceIdString in the supplied INF
  312. //
  313. // rank 31 or 41 (decorated) - only try if we haven't got anything better than 31
  314. //
  315. if(SetupFindFirstLine(InfHandle,MediaListSectionName,SourceIdString,&InfContext)) {
  316. if (InfContext.Inf == InfContext.CurrentInf) {
  317. SelectedRank = 31;
  318. SelectedInfContext = InfContext;
  319. } else if (SelectedRank > 41) {
  320. SelectedRank = 41;
  321. SelectedInfContext = InfContext;
  322. }
  323. }
  324. if (SelectedRank > 32) {
  325. //
  326. // rank 32 or 42 (undecorated) - only try if we haven't got anything better than 32
  327. //
  328. if(SetupFindFirstLine(InfHandle,pszSourceDisksNames,SourceIdString,&InfContext)) {
  329. if (InfContext.Inf == InfContext.CurrentInf) {
  330. SelectedRank = 32;
  331. SelectedInfContext = InfContext;
  332. } else if (SelectedRank > 42) {
  333. SelectedRank = 42;
  334. SelectedInfContext = InfContext;
  335. }
  336. }
  337. }
  338. }
  339. if(SelectedRank == 100 || (Value = pSetupGetField(&InfContext,ValueIndex))==NULL) {
  340. if(Mandatory) {
  341. SetLastError(ERROR_LINE_NOT_FOUND);
  342. return(FALSE);
  343. } else {
  344. Value = TEXT("");
  345. }
  346. }
  347. //
  348. // Figure out how many characters are in the output.
  349. // If the value is a path type value we want to remove
  350. // the trailing backslash if there is one.
  351. //
  352. Length = lstrlen(Value);
  353. if(IsPath && Length && (*CharPrev(Value,Value+Length) == TEXT('\\'))) {
  354. Length--;
  355. }
  356. //
  357. // Need to leave space for the trailing nul.
  358. //
  359. Length++;
  360. if(RequiredSize) {
  361. b = TRUE;
  362. try {
  363. *RequiredSize = Length;
  364. } except(EXCEPTION_EXECUTE_HANDLER) {
  365. b = FALSE;
  366. }
  367. if(!b) {
  368. SetLastError(ERROR_INVALID_PARAMETER);
  369. return(FALSE);
  370. }
  371. }
  372. b = TRUE;
  373. if(ReturnBuffer) {
  374. if(Length <= ReturnBufferSize) {
  375. //
  376. // lstrcpyn is a strange API but the below is correct --
  377. // the size parameter is actually the capacity of the
  378. // target buffer. So to get it to put the nul in the
  379. // right place we pass one larger than the number of chars
  380. // we want copied.
  381. //
  382. if(!lstrcpyn(ReturnBuffer,Value,Length)) {
  383. //
  384. // ReturnBuffer invalid
  385. //
  386. b = FALSE;
  387. SetLastError(ERROR_INVALID_PARAMETER);
  388. }
  389. } else {
  390. b = FALSE;
  391. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  392. }
  393. }
  394. return(b);
  395. }