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.

421 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: S E T U P D I . C P P
  7. //
  8. // Contents: Code to copy Net class inf file
  9. //
  10. // Notes:
  11. //
  12. //----------------------------------------------------------------------------
  13. #include "notify.h"
  14. // =================================================================
  15. // Forward declarations
  16. HRESULT HrCopyMiniportInf (VOID);
  17. HRESULT HrGetProtocolInf (LPWSTR lpszWindowsDir,
  18. LPWSTR *lppszProtocolInf);
  19. HRESULT HrGetMediaRootDir (LPWSTR lpszInfFile,
  20. LPWSTR *lppszMediaRoot);
  21. HRESULT HrGetPnpID (LPWSTR lpszInfFile,
  22. LPWSTR *lppszPnpID);
  23. HRESULT HrGetKeyValue (HINF hInf,
  24. LPCWSTR lpszSection,
  25. LPCWSTR lpszKey,
  26. DWORD dwIndex,
  27. LPWSTR *lppszValue);
  28. const WCHAR c_szInfPath[] = L"Inf\\";
  29. const WCHAR c_szMiniportInf[] = L"mux_mp.inf";
  30. const WCHAR c_szInfSourcePathInfo[] = L"InfSourcePathInfo";
  31. const WCHAR c_szOriginalInfSourcePath[] = L"OriginalInfSourcePath";
  32. HRESULT HrCopyMiniportInf (VOID)
  33. {
  34. LPWSTR lpszWindowsDir;
  35. LPWSTR lpszProtocolInf;
  36. LPWSTR lpszMediaRoot;
  37. LPWSTR lpszMiniportInf;
  38. DWORD dwLen;
  39. HRESULT hr;
  40. //
  41. // Get %windir% directory.
  42. //
  43. dwLen = GetSystemWindowsDirectoryW( NULL, 0 );
  44. if ( dwLen == 0 )
  45. {
  46. return HRESULT_FROM_WIN32(GetLastError());
  47. }
  48. // Add 1 for NULL and 1 for "\" in case it is needed.
  49. dwLen += wcslen(c_szInfPath) + 2;
  50. lpszWindowsDir = (LPWSTR)CoTaskMemAlloc( dwLen * sizeof(WCHAR) );
  51. if ( !lpszWindowsDir )
  52. {
  53. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  54. }
  55. if ( GetSystemWindowsDirectoryW(lpszWindowsDir, dwLen) == 0 )
  56. {
  57. hr = HRESULT_FROM_WIN32( GetLastError() );
  58. }
  59. else
  60. {
  61. // Append "inf\" to %windir%.
  62. dwLen = wcslen( lpszWindowsDir );
  63. if ( lpszWindowsDir[dwLen-1] == L'\\' )
  64. {
  65. wcscat( lpszWindowsDir, c_szInfPath );
  66. }
  67. else
  68. {
  69. wcscat( lpszWindowsDir, L"\\" );
  70. wcscat( lpszWindowsDir, c_szInfPath );
  71. }
  72. //
  73. // Find the protocol inf name. Originally, it was netsf.inf but has
  74. // been renamed to oem?.inf by SetupCopyOEMInf.
  75. //
  76. hr = HrGetProtocolInf( lpszWindowsDir, &lpszProtocolInf );
  77. if ( hr == S_OK )
  78. {
  79. //
  80. // Get the directory from where protocol was installed.
  81. hr = HrGetMediaRootDir( lpszProtocolInf, &lpszMediaRoot );
  82. if ( hr == S_OK )
  83. {
  84. TraceMsg(L"Media root directory is %s.\n", lpszMediaRoot);
  85. // Add 1 for NULL and 1 for "\" in case it is needed.
  86. lpszMiniportInf = (LPWSTR)CoTaskMemAlloc( (wcslen(lpszMediaRoot) +
  87. wcslen(c_szMiniportInf) + 2) *
  88. sizeof(WCHAR) );
  89. if ( lpszMiniportInf == NULL )
  90. {
  91. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  92. }
  93. else
  94. {
  95. //
  96. // We know the full path from where the protocol is being installed. Our
  97. // miniport inf is in the same location. Copy the miniport inf to
  98. // %windir%\inf so that when we install the virtual miniport, Setup
  99. // will find the miniport inf.
  100. //
  101. wcscpy( lpszMiniportInf, lpszMediaRoot );
  102. dwLen = wcslen( lpszMiniportInf );
  103. if ( lpszMiniportInf[dwLen-1] != L'\\' )
  104. {
  105. wcscat( lpszMiniportInf, L"\\" );
  106. }
  107. wcscat( lpszMiniportInf, c_szMiniportInf );
  108. TraceMsg(L"Calling SetupCopyOEMInf for %s.\n", lpszMiniportInf);
  109. if ( !SetupCopyOEMInfW(lpszMiniportInf,
  110. lpszMediaRoot,
  111. SPOST_PATH,
  112. 0,
  113. NULL,
  114. 0,
  115. NULL,
  116. NULL) )
  117. {
  118. hr = HRESULT_FROM_WIN32(GetLastError());
  119. }
  120. CoTaskMemFree( lpszMiniportInf );
  121. }
  122. CoTaskMemFree( lpszMediaRoot );
  123. }
  124. CoTaskMemFree( lpszProtocolInf );
  125. }
  126. }
  127. CoTaskMemFree( lpszWindowsDir );
  128. return hr;
  129. }
  130. //
  131. // The function searches through all the inf files in %windir%\inf and
  132. // returns the name of the protocol's inf.
  133. //
  134. HRESULT HrGetProtocolInf (LPWSTR lpszWindowsDir,
  135. LPWSTR *lppszProtocolInf)
  136. {
  137. LPWSTR lpszFileList;
  138. LPWSTR lpszFile;
  139. LPWSTR lpszFileWithPath;
  140. LPWSTR lpszPnpID;
  141. DWORD dwSizeNeeded;
  142. BOOL fTrailingSlash;
  143. DWORD dwLen;
  144. BYTE found;
  145. HRESULT hr;
  146. *lppszProtocolInf = NULL;
  147. dwLen = wcslen( lpszWindowsDir );
  148. fTrailingSlash = lpszWindowsDir[dwLen-1] == L'\\';
  149. if ( SetupGetInfFileListW(lpszWindowsDir,
  150. INF_STYLE_WIN4,
  151. NULL,
  152. 0,
  153. &dwSizeNeeded) == 0 )
  154. {
  155. return HRESULT_FROM_WIN32(GetLastError());
  156. }
  157. lpszFileList = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
  158. if ( !lpszFileList )
  159. {
  160. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  161. }
  162. if ( SetupGetInfFileListW( lpszWindowsDir,
  163. INF_STYLE_WIN4,
  164. lpszFileList,
  165. dwSizeNeeded,
  166. NULL) == 0 )
  167. {
  168. CoTaskMemFree( lpszFileList );
  169. return HRESULT_FROM_WIN32(GetLastError());
  170. }
  171. lpszFile = lpszFileList;
  172. found = 0;
  173. hr = S_OK;
  174. while( (hr == S_OK) && !found && *lpszFile )
  175. {
  176. lpszFileWithPath = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) *
  177. (wcslen(lpszFile) +
  178. dwLen + 1 +
  179. ((fTrailingSlash) ? 0 : 1)) );
  180. if ( !lpszFileWithPath )
  181. {
  182. hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  183. }
  184. else
  185. {
  186. if ( fTrailingSlash )
  187. {
  188. swprintf( lpszFileWithPath, L"%s%s",
  189. lpszWindowsDir,
  190. lpszFile );
  191. }
  192. else
  193. {
  194. swprintf( lpszFileWithPath, L"%s\\%s",
  195. lpszWindowsDir,
  196. lpszFile );
  197. }
  198. hr = HrGetPnpID( lpszFileWithPath, &lpszPnpID );
  199. // If the inf file installs a driver then, it will have a Model
  200. // section with the hwid/PnpID of the driver that is installed.
  201. //
  202. // In case, there is an error getting the hwid, we simply ignore
  203. // the inf file and continue with the next one.
  204. if ( hr == S_OK )
  205. {
  206. if (_wcsicmp(lpszPnpID, c_szMuxProtocol) == 0 )
  207. {
  208. found = 1;
  209. }
  210. CoTaskMemFree( lpszPnpID );
  211. }
  212. if ( !found )
  213. {
  214. hr = S_OK;
  215. CoTaskMemFree( lpszFileWithPath );
  216. lpszFile += wcslen(lpszFile) + 1;
  217. }
  218. }
  219. }
  220. if ( found )
  221. {
  222. *lppszProtocolInf = lpszFileWithPath;
  223. }
  224. else
  225. {
  226. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  227. }
  228. CoTaskMemFree( lpszFileList );
  229. return hr;
  230. }
  231. HRESULT HrGetPnpID (LPWSTR lpszInfFile,
  232. LPWSTR *lppszPnpID)
  233. {
  234. HINF hInf;
  235. LPWSTR lpszModelSection;
  236. HRESULT hr;
  237. *lppszPnpID = NULL;
  238. hInf = SetupOpenInfFileW( lpszInfFile,
  239. NULL,
  240. INF_STYLE_WIN4,
  241. NULL );
  242. if ( hInf == INVALID_HANDLE_VALUE )
  243. {
  244. return HRESULT_FROM_WIN32(GetLastError());
  245. }
  246. hr = HrGetKeyValue( hInf,
  247. L"Manufacturer",
  248. NULL,
  249. 1,
  250. &lpszModelSection );
  251. if ( hr == S_OK )
  252. {
  253. hr = HrGetKeyValue( hInf,
  254. lpszModelSection,
  255. NULL,
  256. 2,
  257. lppszPnpID );
  258. CoTaskMemFree( lpszModelSection );
  259. }
  260. SetupCloseInfFile( hInf );
  261. return hr;
  262. }
  263. HRESULT HrGetMediaRootDir (LPWSTR lpszInfFile,
  264. LPWSTR *lppszMediaRoot)
  265. {
  266. HINF hInf;
  267. HRESULT hr;
  268. *lppszMediaRoot = NULL;
  269. hInf = SetupOpenInfFileW( lpszInfFile,
  270. NULL,
  271. INF_STYLE_WIN4,
  272. NULL );
  273. if ( hInf == INVALID_HANDLE_VALUE )
  274. {
  275. return HRESULT_FROM_WIN32(GetLastError());
  276. }
  277. //
  278. // Contained within the protocol INF should be a [InfSourcePathInfo]
  279. // section with the following entry:
  280. //
  281. // OriginalInfSourcePath = %1%
  282. //
  283. // If we retrieve the value (i.e., field 1) of this line, we'll get the
  284. // full path where the INF originally came from.
  285. //
  286. hr = HrGetKeyValue( hInf,
  287. c_szInfSourcePathInfo,
  288. c_szOriginalInfSourcePath,
  289. 1,
  290. lppszMediaRoot );
  291. SetupCloseInfFile( hInf );
  292. return hr;
  293. }
  294. HRESULT HrGetKeyValue (HINF hInf,
  295. LPCWSTR lpszSection,
  296. LPCWSTR lpszKey,
  297. DWORD dwIndex,
  298. LPWSTR *lppszValue)
  299. {
  300. INFCONTEXT infCtx;
  301. DWORD dwSizeNeeded;
  302. HRESULT hr;
  303. *lppszValue = NULL;
  304. if ( SetupFindFirstLineW(hInf,
  305. lpszSection,
  306. lpszKey,
  307. &infCtx) == FALSE )
  308. {
  309. return HRESULT_FROM_WIN32(GetLastError());
  310. }
  311. SetupGetStringFieldW( &infCtx,
  312. dwIndex,
  313. NULL,
  314. 0,
  315. &dwSizeNeeded );
  316. *lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
  317. if ( !*lppszValue )
  318. {
  319. return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  320. }
  321. if ( SetupGetStringFieldW(&infCtx,
  322. dwIndex,
  323. *lppszValue,
  324. dwSizeNeeded,
  325. NULL) == FALSE )
  326. {
  327. hr = HRESULT_FROM_WIN32(GetLastError());
  328. CoTaskMemFree( *lppszValue );
  329. *lppszValue = NULL;
  330. }
  331. else
  332. {
  333. hr = S_OK;
  334. }
  335. return hr;
  336. }