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.

481 lines
13 KiB

  1. /*----------------------------------------------------------------------------
  2. | mmdriver.c - Install Multimedia Drivers
  3. |
  4. | Copyright (C) Microsoft, 1989, 1990. All Rights Reserved
  5. |
  6. | History:
  7. | 09/11/90 davidle created
  8. | Install Multimedia Drivers
  9. |
  10. | Tue Jan 29 1991 -by- MichaelE
  11. | Redesigned installing installable drivers so additional drivers
  12. | can be installed by adding them to setup.inf's [installable.drivers]
  13. |
  14. | Wed Mar 20 1991 -by- MichaelE
  15. | Changed mmAddInstallableDriver to accept multiple VxDs.
  16. | Changed and WriteNextPrivateProfileString to check if the profile
  17. | being concatenated is already there.
  18. |
  19. | Sun Apr 14 1991 -by- MichaelE
  20. | WriteNextPrivateProfileString -> Next386EnhDevice.
  21. |
  22. | Sun Apr 14 1991 -by- JohnYG
  23. | Taken from setup for drivers applet.
  24. |
  25. | Wed Jun 05 1991 -by- MichaelE
  26. | Added FileCopy of associated file list to windows system dir.
  27. |
  28. *----------------------------------------------------------------------------*/
  29. #include <windows.h>
  30. #include <mmsystem.h>
  31. #include <winsvc.h>
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include "drivers.h"
  35. #include "sulib.h"
  36. /*
  37. * Local functions
  38. */
  39. static BOOL mmAddInstallableDriver (PINF, LPTSTR, LPTSTR, PIDRIVER );
  40. static BOOL GetDrivers (PINF, LPTSTR, LPTSTR);
  41. /**************************************************************************
  42. *
  43. * AccessServiceController()
  44. *
  45. * Check we will be able to access the service controller to install
  46. * a driver
  47. *
  48. * returns FALSE if we can't get access - otherwise TRUE
  49. *
  50. **************************************************************************/
  51. BOOL AccessServiceController(void)
  52. {
  53. SC_HANDLE SCManagerHandle;
  54. SCManagerHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  55. if (SCManagerHandle == NULL) {
  56. return FALSE;
  57. }
  58. CloseServiceHandle(SCManagerHandle);
  59. return TRUE;
  60. }
  61. /**************************************************************************
  62. *
  63. * mmDisplayInfFileErrMsg()
  64. *
  65. * This function displays an error message when the inf file contains
  66. * corrupt data.
  67. *
  68. **************************************************************************/
  69. void mmDisplayInfFileErrMsg( void )
  70. {
  71. TCHAR strBuf[MAXSTR];
  72. /*
  73. * We do not want to report any errors that occur while installing
  74. * related drivers to the user
  75. */
  76. if( bCopyingRelated )
  77. {
  78. return;
  79. }
  80. LoadString(myInstance, IDS_INVALIDINF, strBuf, MAXSTR);
  81. MessageBox(hMesgBoxParent,
  82. strBuf,
  83. szFileError,
  84. MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
  85. }
  86. /**************************************************************************
  87. *
  88. * mmAddNewDriver() - only exported function in this file.
  89. *
  90. * This function installs (copies) a driver
  91. *
  92. * returns FALSE if no drivers could be installed.
  93. * TRUE if at least one driver installation was sucessful.
  94. * All added types in lpszNewTypes buffer.
  95. *
  96. **************************************************************************/
  97. BOOL mmAddNewDriver( LPTSTR lpstrDriver, LPTSTR lpstrNewTypes, PIDRIVER pIDriver )
  98. {
  99. PINF pinf;
  100. if ((pinf = FindInstallableDriversSection(NULL)) == NULL)
  101. return FALSE;
  102. return mmAddInstallableDriver(pinf, lpstrDriver, lpstrNewTypes, pIDriver);
  103. }
  104. /**************************************************************************
  105. * mmAddInstallableDriver() - Do the dirty work looking for VxD's copying them
  106. * looking for drivers, copying them, and returning the best type names.
  107. *
  108. *
  109. **************************************************************************/
  110. BOOL mmAddInstallableDriver( PINF pInfIDrivers,
  111. LPTSTR pstrDriver,
  112. LPTSTR lpstrNewTypes,
  113. PIDRIVER pIDriver)
  114. {
  115. LPTSTR pstr, pstrSection;
  116. static TCHAR szTemp[10];
  117. PINF pInfSection= pInfIDrivers;
  118. LONG lResult;
  119. int i;
  120. TCHAR szBuffer[MAX_INF_LINE_LEN],
  121. szFilename[MAXSTR],
  122. szType[MAX_SECT_NAME_LEN];
  123. /*
  124. * format of a line in [installable.drivers] of setup.inf:
  125. * driver profile = [0]
  126. * filename, [1]
  127. * "type(s)", [2]
  128. * "description", [3]
  129. * "VxD and .sys filename(s)",[4]
  130. * "default config params" [5]
  131. * "Related drivers" [6]
  132. *
  133. * find the driver profile line in szMDrivers we are installing
  134. */
  135. while ( TRUE )
  136. {
  137. lResult = infParseField( pInfIDrivers, 0, szBuffer, SIZEOF(szBuffer) );
  138. if( INF_PARSE_FAILED(lResult) )
  139. {
  140. mmDisplayInfFileErrMsg();
  141. return FALSE;
  142. }
  143. if ( lstrcmpi( szBuffer, pstrDriver ) == 0 )
  144. break;
  145. else if ( ! (pInfIDrivers = infNextLine( pInfIDrivers )) )
  146. return FALSE;
  147. }
  148. /*
  149. * copy the driver file and add driver type(s) to the installable
  150. * driver section
  151. */
  152. if ( infParseField(pInfIDrivers, 1, szFilename, SIZEOF(szFilename)) != ERROR_SUCCESS )
  153. {
  154. mmDisplayInfFileErrMsg();
  155. return FALSE;
  156. }
  157. /*
  158. * Ignore the disk number
  159. */
  160. wcscpy(szDrv, RemoveDiskId(szFilename));
  161. /*
  162. * Cache whether it's a kernel driver
  163. */
  164. pIDriver->KernelDriver = IsFileKernelDriver(szFilename);
  165. /*
  166. * Can't install kernel drivers if don't have privilege
  167. */
  168. if (pIDriver->KernelDriver && !AccessServiceController()) {
  169. TCHAR szMesg[MAXSTR];
  170. TCHAR szMesg2[MAXSTR];
  171. TCHAR szTitle[50];
  172. LoadString(myInstance, IDS_INSUFFICIENT_PRIVILEGE, szMesg, sizeof(szMesg)/sizeof(TCHAR));
  173. LoadString(myInstance, IDS_CONFIGURE_DRIVER, szTitle, sizeof(szTitle)/sizeof(TCHAR));
  174. wsprintf(szMesg2, szMesg, szDrv);
  175. MessageBox(hMesgBoxParent, szMesg2, szTitle, MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL);
  176. return FALSE;
  177. }
  178. /*
  179. * Do the file copying
  180. */
  181. if (FileCopy( szFilename,
  182. szSystem,
  183. (FPFNCOPY)wsCopySingleStatus,
  184. FC_FILE ) != NO_ERROR) {
  185. return FALSE;
  186. }
  187. /*
  188. * Add options
  189. */
  190. lResult = infParseField (pInfIDrivers,5,szBuffer+1, SIZEOF(szBuffer)-1);
  191. if( INF_PARSE_FAILED(lResult) )
  192. {
  193. mmDisplayInfFileErrMsg();
  194. return FALSE;
  195. }
  196. else if( lResult == ERROR_SUCCESS )
  197. {
  198. szBuffer[0]=TEXT(' ');
  199. lstrcat(szFilename,szBuffer);
  200. }
  201. /*
  202. * copy filename and options
  203. */
  204. wcsncpy(pIDriver->szFile, FileName(szFilename), sizeof(pIDriver->szFile)/sizeof(TCHAR));
  205. pIDriver->szFile[sizeof(pIDriver->szFile)/sizeof(TCHAR) - 1] = 0;
  206. /*
  207. * copy description
  208. */
  209. lResult = infParseField( pInfIDrivers, 3, pIDriver->szDesc, SIZEOF(pIDriver->szDesc) );
  210. if( INF_PARSE_FAILED(lResult) )
  211. {
  212. mmDisplayInfFileErrMsg();
  213. return FALSE;
  214. }
  215. /*
  216. * determine the section from the description. A kernel driver
  217. * will appear as a driver of type 'KERNEL' in system.ini
  218. *
  219. * If the description contains [MCI] then it's MCI.
  220. */
  221. if (wcsstr(pIDriver->szDesc, TEXT("MCI")))
  222. pstrSection = szMCI;
  223. else
  224. pstrSection = szDrivers;
  225. /*
  226. * Copy name plus parameters to our driver data
  227. */
  228. wcsncpy(pIDriver->szSection, pstrSection, sizeof(pIDriver->szSection)/sizeof(TCHAR));
  229. pIDriver->szSection[sizeof(pIDriver->szSection)/sizeof(TCHAR) - 1] = TEXT('\0');
  230. wcscpy(pIDriver->wszSection, pIDriver->szSection);
  231. /*
  232. * We return all types in a parseable, contcatentated string
  233. */
  234. lResult = infParseField( pInfIDrivers, 2, szBuffer, SIZEOF(szBuffer) );
  235. if( INF_PARSE_FAILED(lResult) )
  236. {
  237. mmDisplayInfFileErrMsg();
  238. return FALSE;
  239. }
  240. for ( i = 1; ; i++ )
  241. {
  242. lResult = infParseField( szBuffer, i, szType, SIZEOF(szType) );
  243. if( INF_PARSE_FAILED(lResult) )
  244. {
  245. mmDisplayInfFileErrMsg();
  246. return FALSE;
  247. }
  248. else if( lResult != ERROR_SUCCESS )
  249. {
  250. break;
  251. }
  252. pstr = &(szType[lstrlen(szType)]);
  253. *pstr++ = TEXT(',');
  254. *pstr = 0;
  255. lstrcat(lpstrNewTypes, szType );
  256. }
  257. if (!*lpstrNewTypes)
  258. /*
  259. * We weren't able to return any types.
  260. */
  261. return FALSE;
  262. /*
  263. * copy an associated file list (if it exists) to windows system dir
  264. */
  265. if (FileCopy(pstrDriver,
  266. szSystem,
  267. (FPFNCOPY)wsCopySingleStatus,
  268. FC_SECTION) != ERROR_SUCCESS)
  269. return(FALSE);
  270. /*
  271. * if there are system driver files copy them to the system
  272. * drivers directory.
  273. *
  274. * NOTE that it is assumed here that any installation and
  275. * configuration for these drivers is performed by the main
  276. * (.drv) driver being installed.
  277. *
  278. */
  279. lResult = infParseField( pInfIDrivers, 4, szBuffer, SIZEOF(szBuffer) );
  280. if( INF_PARSE_FAILED(lResult) )
  281. {
  282. mmDisplayInfFileErrMsg();
  283. return FALSE;
  284. }
  285. if ( (lResult == ERROR_SUCCESS) && szBuffer[0] )
  286. {
  287. for ( i = 1; ; i++ )
  288. {
  289. lResult = infParseField( szBuffer, i, szFilename, SIZEOF(szFilename) );
  290. if( INF_PARSE_FAILED(lResult) )
  291. {
  292. mmDisplayInfFileErrMsg();
  293. return FALSE;
  294. }
  295. else if( lResult != ERROR_SUCCESS )
  296. {
  297. break;
  298. }
  299. wcscpy(szDrv, RemoveDiskId(szFilename));
  300. /*
  301. * FileCopy will adjust the 'system' directory to
  302. * system\drivers. It's done this way because FileCopy
  303. * must anyway look for old files in the same directory.
  304. */
  305. if (FileCopy(szFilename,
  306. szSystem,
  307. (FPFNCOPY)wsCopySingleStatus,
  308. FC_FILE )
  309. != ERROR_SUCCESS)
  310. {
  311. return FALSE;
  312. }
  313. }
  314. }
  315. #ifdef DOBOOT // Don't do boot section on NT
  316. lResult = infParseField(pInfIDrivers, 7, szTemp, SIZEOF(szTemp));
  317. if( INF_PARSE_FAILED(lResult) )
  318. {
  319. mmDisplayInfFileErrMsg();
  320. return FALSE;
  321. }
  322. if (!_strcmpi(szTemp, szBoot))
  323. bInstallBootLine = TRUE;
  324. #endif // DOBOOT
  325. /*
  326. * Read the related drivers list (drivers which must/can also be
  327. * be installed).
  328. */
  329. if (bRelated == FALSE)
  330. {
  331. lResult = infParseField(pInfIDrivers, 6, pIDriver->szRelated, SIZEOF(pIDriver->szRelated));
  332. if( INF_PARSE_FAILED(lResult) )
  333. {
  334. mmDisplayInfFileErrMsg();
  335. return FALSE;
  336. }
  337. if (wcslen(pIDriver->szRelated))
  338. {
  339. if( !GetDrivers(pInfSection, pIDriver->szRelated, pIDriver->szRemove) )
  340. {
  341. mmDisplayInfFileErrMsg();
  342. return FALSE;
  343. }
  344. pIDriver->bRelated = TRUE;
  345. bRelated = TRUE;
  346. }
  347. }
  348. return TRUE;
  349. }
  350. /*
  351. * Used to get the list of the related driver filenames
  352. *
  353. * pInfIDrivers - Pointer to the [installable.drivers] section or equivalent
  354. * szAliasList - List of driver aliases (ie key values - eg msalib).
  355. * szDriverList - List of drivers file names found
  356. */
  357. BOOL GetDrivers(PINF pInfIDrivers, LPTSTR szAliasList, LPTSTR szDriverList)
  358. {
  359. TCHAR szBuffer[50];
  360. TCHAR szAlias[50];
  361. TCHAR szFileName[50];
  362. PINF pInfILocal;
  363. LONG lResult;
  364. BOOL bEnd;
  365. int i;
  366. for ( i = 1; ; i++ )
  367. {
  368. lResult = infParseField(szAliasList, i, szAlias, SIZEOF(szAlias));
  369. if( INF_PARSE_FAILED(lResult) )
  370. {
  371. return FALSE;
  372. }
  373. else if( lResult != ERROR_SUCCESS )
  374. {
  375. break;
  376. }
  377. pInfILocal = pInfIDrivers;
  378. bEnd = FALSE;
  379. while (!bEnd)
  380. {
  381. lResult = infParseField( pInfILocal, 0, szBuffer, SIZEOF(szBuffer));
  382. if( INF_PARSE_FAILED(lResult) )
  383. {
  384. return FALSE;
  385. }
  386. if (lstrcmpi( szBuffer, szAlias) == 0 )
  387. {
  388. lResult = infParseField(pInfILocal, 1, szFileName, SIZEOF(szFileName));
  389. if( INF_PARSE_FAILED(lResult) )
  390. {
  391. return FALSE;
  392. }
  393. else if( lResult == ERROR_SUCCESS )
  394. {
  395. lstrcat(szDriverList, RemoveDiskId(szFileName));
  396. lstrcat(szDriverList, TEXT(","));
  397. }
  398. break;
  399. }
  400. else
  401. if ( ! (pInfILocal = infNextLine( pInfILocal )) )
  402. bEnd = TRUE;
  403. }
  404. }
  405. return TRUE;
  406. }