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.

234 lines
4.3 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. infcache.c
  5. Abstract:
  6. This module implements a simple inf caching mechanism.
  7. WARNING: THE CODE IN THIS MODULE IS NOT MULTI-THREAD SAFE.
  8. EXERCISE EXTREME CAUTION WHEN MAKING USE OF THESE ROUTINES.
  9. Author:
  10. Ted Miller (tedm) 28-Aug-1995
  11. Revision History:
  12. --*/
  13. #include "setupp.h"
  14. #pragma hdrstop
  15. //
  16. // Structure for cached inf. We assume that there won't be
  17. // too many of these open at the same time so we just keep
  18. // a linear list.
  19. //
  20. typedef struct _INFC {
  21. struct _INFC *Next;
  22. //
  23. // Name of INF
  24. //
  25. PCWSTR Filename;
  26. //
  27. // Handle to inf.
  28. //
  29. HINF InfHandle;
  30. } INFC, *PINFC;
  31. PINFC OpenInfList;
  32. HINF
  33. InfCacheOpenInf(
  34. IN PCWSTR FileName,
  35. IN PCWSTR InfType OPTIONAL
  36. )
  37. /*++
  38. Routine Description:
  39. Open a (win95-style) inf file if it has not already been opened
  40. via the cached inf mechanism.
  41. Arguments:
  42. FileName - supplies name of inf file to be opened. Matching is
  43. based solely on this string as given here; no processing on it
  44. is performed and no attempt is made to determine where the inf
  45. file is actually located.
  46. InfType - if specified supplies an argument to be passed to
  47. SetupOpenInfFile() as the InfType parameter.
  48. Return Value:
  49. Handle of inf file if successful; NULL if not.
  50. --*/
  51. {
  52. PINFC p;
  53. HINF h;
  54. //
  55. // Look for inf to see if it's already open.
  56. //
  57. for(p=OpenInfList; p; p=p->Next) {
  58. if(!lstrcmpi(p->Filename,FileName)) {
  59. return(p->InfHandle);
  60. }
  61. }
  62. h = SetupOpenInfFile(FileName,InfType,INF_STYLE_WIN4,NULL);
  63. if(h == INVALID_HANDLE_VALUE) {
  64. return(NULL);
  65. }
  66. p = MyMalloc(sizeof(INFC));
  67. if(!p) {
  68. SetupCloseInfFile(h);
  69. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  70. return(NULL);
  71. }
  72. p->Filename = pSetupDuplicateString(FileName);
  73. if(!p->Filename) {
  74. MyFree(p);
  75. SetupCloseInfFile(h);
  76. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  77. return(NULL);
  78. }
  79. p->InfHandle = h;
  80. p->Next = OpenInfList;
  81. OpenInfList = p;
  82. return(h);
  83. }
  84. HINF
  85. InfCacheOpenLayoutInf(
  86. IN HINF InfHandle
  87. )
  88. {
  89. INFCONTEXT InfContext;
  90. BOOL b;
  91. DWORD DontCare;
  92. HINF h;
  93. WCHAR FileName[MAX_PATH],TempName[MAX_PATH];
  94. PINFC p;
  95. //
  96. // Fetch the name of the layout inf.
  97. // Note that an INF is perfectly capable of acting as its own layout inf.
  98. //
  99. if(SetupFindFirstLine(InfHandle,L"Version",L"LayoutFile",&InfContext)) {
  100. if(SetupGetStringField(&InfContext,1,FileName,MAX_PATH,&DontCare)) {
  101. //
  102. // Open the layout inf. If first attempt fails,
  103. // try opening it in the current directory (unqualified inf names
  104. // will be looked for in %sysroot%\inf, which might not be what
  105. // we want).
  106. //
  107. h = InfCacheOpenInf(FileName,NULL);
  108. if(!h) {
  109. TempName[0] = L'.';
  110. TempName[1] = 0;
  111. pSetupConcatenatePaths(TempName,FileName,MAX_PATH,NULL);
  112. h = InfCacheOpenInf(TempName,NULL);
  113. }
  114. } else {
  115. //
  116. // INF is corrupt
  117. //
  118. h = NULL;
  119. }
  120. } else {
  121. //
  122. // No layout inf: inf is its own layout inf
  123. //
  124. h = InfHandle;
  125. }
  126. return(h);
  127. }
  128. VOID
  129. InfCacheEmpty(
  130. IN BOOL CloseInfs
  131. )
  132. {
  133. PINFC p,q;
  134. HINF h;
  135. for(p=OpenInfList; p; ) {
  136. q = p->Next;
  137. if(CloseInfs) {
  138. SetupCloseInfFile(p->InfHandle);
  139. }
  140. MyFree(p->Filename);
  141. MyFree(p);
  142. p = q;
  143. }
  144. }
  145. BOOL
  146. InfCacheRefresh(
  147. VOID
  148. )
  149. /*++
  150. Routine Description:
  151. Refresh all of the open cached inf files.
  152. Arguments:
  153. None.
  154. Return Value:
  155. TRUE on success.
  156. Note: This routine can be used to reopen all cached infs in the current
  157. context. This could be necessary if the locale changes, for instance.
  158. --*/
  159. {
  160. PINFC p,q;
  161. HINF h;
  162. BOOL bRet = TRUE;
  163. for(p=OpenInfList; p; ) {
  164. q = p->Next;
  165. SetupCloseInfFile(p->InfHandle);
  166. p->InfHandle = SetupOpenInfFile(p->Filename,NULL,INF_STYLE_WIN4,NULL);
  167. bRet = (p->InfHandle == INVALID_HANDLE_VALUE) ? FALSE : bRet;
  168. p = q;
  169. }
  170. return bRet;
  171. }