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.

873 lines
26 KiB

  1. /******************************************************************************
  2. Copyright (C) Microsoft Corporation 1985-1990. All rights reserved.
  3. Title: drvrrare.c - Installable driver code. Less common code
  4. Version: 1.00
  5. Date: 10-Jun-1990
  6. Author: DAVIDDS ROBWI
  7. *****************************************************************************/
  8. #include <windows.h>
  9. #include "drvr.h"
  10. #define MMNOSOUND
  11. #define MMNOWAVE
  12. #define MMNOMIDI
  13. #define MMNOSEQ
  14. #define MMNOTIMER
  15. #define MMNOJOY
  16. #define MMNOMCI
  17. #include "mmsystem.h"
  18. #define NOTIMERDEV
  19. #define NOJOYDEV
  20. #define NOMCIDEV
  21. #define NOSEQDEV
  22. #define NOWAVEDEV
  23. #define NOMIDIDEV
  24. #define NOTASKDEV
  25. #include "mmddk.h"
  26. #include "mmsysi.h"
  27. extern HANDLE hInstalledDriverList; // List of installed driver instances
  28. extern int cInstalledDrivers; // High water count of installed driver instances
  29. extern DWORD FAR PASCAL DriverProc(DWORD dwID, HANDLE hdrv, WORD msg, DWORD dw1, DWORD dw2);
  30. /* Support for using 3.1 APIs if available */
  31. typedef HANDLE (FAR PASCAL *OPENDRIVER31)(LPSTR, LPSTR, LONG);
  32. typedef LONG (FAR PASCAL *CLOSEDRIVER31)(HANDLE, LONG, LONG);
  33. typedef HANDLE (FAR PASCAL *GETDRIVERMODULEHANDLE31)(HANDLE);
  34. typedef LONG (FAR PASCAL *SENDDRIVERMESSAGE31)(HANDLE, WORD, LONG, LONG);
  35. typedef LONG (FAR PASCAL *DEFDRIVERPROC31)(DWORD, HANDLE, WORD, LONG, LONG);
  36. OPENDRIVER31 lpOpenDriver;
  37. CLOSEDRIVER31 lpCloseDriver;
  38. GETDRIVERMODULEHANDLE31 lpGetDriverModuleHandle;
  39. SENDDRIVERMESSAGE31 lpSendDriverMessage;
  40. DEFDRIVERPROC31 lpDefDriverProc;
  41. BOOL fUseWinAPI;
  42. #pragma alloc_text( INIT, DrvInit )
  43. /***************************************************************************
  44. strings
  45. ****************************************************************************/
  46. extern char far szSystemIni[]; // INIT.C
  47. extern char far szDrivers[];
  48. extern char far szBoot[];
  49. extern char far szNull[];
  50. extern char far szUser[];
  51. extern char far szOpenDriver[];
  52. extern char far szCloseDriver[];
  53. extern char far szDrvModuleHandle[];
  54. extern char far szSendDriverMessage[];
  55. extern char far szDefDriverProc[];
  56. extern char far szDriverProc[];
  57. /***************************************************************************
  58. *
  59. * @doc DDK
  60. *
  61. * @api LONG | DrvClose | This function closes an open driver
  62. * instance and decrements
  63. * the driver's open count. Once the driver's open count becomes zero,
  64. * the driver is unloaded.
  65. *
  66. * @parm HANDLE | hDriver | Specifies the handle of the installable
  67. * driver to close.
  68. *
  69. * @parm LONG | lParam1 | Specifies the first message parameter for
  70. * the DRV_CLOSE message. This data is passed directly to the driver.
  71. *
  72. * @parm LONG | lParam2 | Specifies the second message parameter
  73. * for DRV_CLOSE message. This data is passed directly to the driver.
  74. *
  75. * @rdesc Returns zero if the driver aborted the close;
  76. * otherwise, returns the return result from the driver.
  77. * @xref DrvOpen
  78. *
  79. ***************************************************************************/
  80. LONG API DrvClose(HANDLE hDriver, LONG lParam1, LONG lParam2)
  81. {
  82. /* The driver will receive the following message sequence:
  83. *
  84. * DRV_CLOSE
  85. * if DRV_CLOSE returns non-zero
  86. * if driver usage count = 1
  87. * DRV_DISABLE
  88. * DRV_FREE
  89. */
  90. if (fUseWinAPI)
  91. return ((*lpCloseDriver)(hDriver, lParam1, lParam2));
  92. else
  93. return InternalCloseDriver(hDriver, lParam1, lParam2, TRUE);
  94. }
  95. /***************************************************************************
  96. *
  97. * @doc DDK
  98. *
  99. * @api LONG | DrvOpen | This function opens an installable driver.
  100. * The first time a driver is opened it is loaded
  101. * and enabled. A driver must be opened before messages are sent
  102. * to it.
  103. *
  104. * @parm LPSTR | szDriverName | Specifies a far pointer to a
  105. * null-terminated character string
  106. * containing a driver filename or a keyname from a
  107. * section of the SYSTEM.INI file.
  108. *
  109. * @parm LPSTR | szSectionName | Specifies a far pointer to a
  110. * null-terminated character string containing the name of
  111. * the driver section to search. If <p szSectionName> is
  112. * not null, the specified section of the SYSTEM.INI file is
  113. * searched instead of the [Drivers] section. If
  114. * <p szSectionName> is null, the default [Drivers] section is used.
  115. *
  116. * @parm LONG | lParam | Specifies a message parameter to
  117. * pass to the driver procedure with the <m DRV_OPEN> message.
  118. *
  119. * @rdesc Returns a handle to the driver.
  120. *
  121. * @comm Installable drivers must export a <f DriverProc> routine of
  122. * the form:
  123. *
  124. * @cb LONG FAR PASCAL | DriverProc | This entry point receives the
  125. * messages sent to an installable driver. This entry will always
  126. * handle the system messages as a minimum set of messages.
  127. *
  128. * @parm DWORD | dwDriverIdentifier | Specifies the device driver
  129. * identifier.
  130. *
  131. * @parm HANDLE | hDriver | Specifies the device driver handle.
  132. *
  133. * @parm WORD | wMessage | Specifies the message for the device
  134. * driver.
  135. *
  136. * @parm LONG | lParm1 | Specifies message dependent data.
  137. *
  138. * @parm LONG | lParm2 | Specifies message dependent data.
  139. *
  140. * @xref DrvClose
  141. *
  142. ****************************************************************************/
  143. HANDLE API DrvOpen(LPSTR szDriverName,
  144. LPSTR szSectionName,
  145. LONG lParam2)
  146. {
  147. /* The driver will receive the following message sequence:
  148. *
  149. * if driver not loaded and can be found
  150. * DRV_LOAD
  151. * if DRV_LOAD returns non-zero
  152. * DRV_ENABLE
  153. * if driver loaded correctly
  154. * DRV_OPEN
  155. */
  156. HANDLE hdrv;
  157. if (fUseWinAPI)
  158. hdrv = ((*lpOpenDriver)(szDriverName, szSectionName, lParam2));
  159. else
  160. hdrv = (HANDLE)InternalOpenDriver(szDriverName, szSectionName, lParam2, TRUE);
  161. #ifdef DEBUG
  162. if (hdrv) {
  163. char ach[80];
  164. static SZCODE szFormat[] = "MMSYSTEM: Opened %ls (%ls)\r\n";
  165. GetModuleFileName(DrvGetModuleHandle(hdrv), ach, sizeof(ach));
  166. DPRINTF((szFormat, (LPSTR)szDriverName, (LPSTR)ach));
  167. }
  168. #endif
  169. return hdrv;
  170. }
  171. /***************************************************************************
  172. *
  173. * @doc DDK
  174. *
  175. * @api HANDLE | DrvGetModuleHandle | This function returns the library
  176. * module handle of the specified installable driver.
  177. *
  178. * @parm HANDLE | hDriver | Specifies the handle of the installable driver.
  179. *
  180. * @rdesc Returns the module handle of the driver specified by the
  181. * driver handle <p hDriver>.
  182. *
  183. * @comm A module handle is not the same as an installable driver handle.
  184. *
  185. ***************************************************************************/
  186. HANDLE API DrvGetModuleHandle(HANDLE hDriver)
  187. {
  188. LPDRIVERTABLE lpdt;
  189. HANDLE h = 0;
  190. if (fUseWinAPI)
  191. return ((*lpGetDriverModuleHandle)(hDriver));
  192. if (hDriver && ((WORD)hDriver <= cInstalledDrivers))
  193. {
  194. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  195. h = lpdt[hDriver-1].hModule;
  196. GlobalUnlock(hInstalledDriverList);
  197. }
  198. return(h);
  199. }
  200. LONG FAR PASCAL InternalCloseDriver(WORD hDriver,
  201. LONG lParam1,
  202. LONG lParam2,
  203. BOOL fSendDisable)
  204. {
  205. LPDRIVERTABLE lpdt;
  206. LONG result;
  207. HANDLE h;
  208. int index;
  209. BOOL f;
  210. // check handle in valid range.
  211. if (hDriver > cInstalledDrivers)
  212. return(FALSE);
  213. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  214. result = DrvSendMessage(hDriver, DRV_CLOSE, lParam1, lParam2);
  215. if (result)
  216. {
  217. // Driver didn't abort close
  218. f = lpdt[hDriver-1].fFirstEntry;
  219. if (InternalFreeDriver(hDriver, fSendDisable) && f)
  220. {
  221. /* Only one entry for the driver in the driver list has the first
  222. * instance flag set. This is to make it easier to handle system
  223. * messages that only need to be sent to a driver once.
  224. *
  225. * To maintain the flag, we must set the flag in one of the other
  226. * entries if we remove the driver entry with the flag set.
  227. *
  228. * Note that InternalFreeDriver returns the new usage count of
  229. * the driver so if it is zero, we know that there are no other
  230. * entries for the driver in the list and so we don't have to
  231. * do this loop.
  232. */
  233. for (index=0;index<cInstalledDrivers;index++)
  234. if (lpdt[index].hModule == lpdt[hDriver-1].hModule && !lpdt[index].fFirstEntry)
  235. {
  236. lpdt[index].fFirstEntry = 1;
  237. break;
  238. }
  239. }
  240. }
  241. GlobalUnlock(hInstalledDriverList);
  242. return(result);
  243. }
  244. LONG FAR PASCAL InternalOpenDriver(LPSTR szDriverName,
  245. LPSTR szSectionName,
  246. LONG lParam2,
  247. BOOL fSendEnable)
  248. {
  249. int hDriver;
  250. LPDRIVERTABLE lpdt;
  251. LONG result;
  252. HANDLE h;
  253. char sz[128];
  254. if (hDriver = LOWORD(InternalLoadDriver(szDriverName,
  255. szSectionName,
  256. sz,
  257. sizeof(sz),
  258. fSendEnable)))
  259. {
  260. /*
  261. Set the driver identifier to the DRV_OPEN call to the
  262. driver handle. This will let people build helper functions
  263. that the driver can call with a unique identifier if they
  264. want to.
  265. */
  266. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  267. lpdt[hDriver-1].dwDriverIdentifier = hDriver;
  268. GlobalUnlock(hInstalledDriverList);
  269. result = DrvSendMessage(hDriver,
  270. DRV_OPEN,
  271. (LONG)(LPSTR)sz,
  272. lParam2);
  273. if (!result)
  274. InternalFreeDriver(hDriver, fSendEnable);
  275. else
  276. {
  277. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  278. lpdt[hDriver-1].dwDriverIdentifier = result;
  279. GlobalUnlock(hInstalledDriverList);
  280. result = hDriver;
  281. }
  282. }
  283. else
  284. result = 0L;
  285. return(result);
  286. }
  287. /***************************************************************************
  288. *
  289. * @doc INTERNAL
  290. *
  291. * @api LONG | InternalLoadDriver | Loads an installable driver. If this is
  292. * the first time that the driver is opened, the driver will be loaded
  293. * and enabled.
  294. *
  295. * @parm LPSTR | szDriverName | A null-terminated character string
  296. * containing a driver filename or a keyname from the [Drivers]
  297. * section of system.ini.
  298. *
  299. * @parm LPSTR | szSectionName | A null-terminated character string
  300. * that specifies a driver section to search. If szSectionName is
  301. * not null, the specified section of system.ini is searched instead
  302. * of the [Drivers] section. If szSectionName is null, the
  303. * default [Drivers] section is used.
  304. *
  305. * @parm LPSTR | lpstrTail | caller supplied buffer to return the "tail"
  306. * of the system.ini line in. The tail is any characters that follow
  307. * the filename.
  308. *
  309. * @parm WORD | cbTail | size of supplied buffer.
  310. *
  311. * @parm BOOL | fSendEnable | TRUE if driver should be enabled
  312. *
  313. * @rdesc Returns a long whose loword is the handle to the driver and whose
  314. * high word is an error code or the module handle
  315. *
  316. * @xref InternalOpenDriver
  317. *
  318. ****************************************************************************/
  319. LONG FAR PASCAL InternalLoadDriver(LPSTR szDriverName,
  320. LPSTR szSectionName,
  321. LPSTR lpstrTail,
  322. WORD cbTail,
  323. BOOL fSendEnable)
  324. {
  325. int index;
  326. LPDRIVERTABLE lpdt;
  327. LONG result;
  328. HANDLE h;
  329. /* The driver will receive the following message sequence:
  330. *
  331. * if driver not loaded and can be found
  332. * DRV_LOAD
  333. * if DRV_LOAD returns non-zero and fSendEnable
  334. * DRV_ENABLE
  335. */
  336. /* Allocate a table entry */
  337. if (!hInstalledDriverList)
  338. h = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)((WORD)sizeof(DRIVERTABLE)));
  339. else
  340. /* Alloc space for the next driver we will install. We may not really
  341. * install the driver in the last entry but rather in an intermediate
  342. * entry which was freed.
  343. */
  344. h = GlobalReAlloc(hInstalledDriverList,
  345. (DWORD)((WORD)sizeof(DRIVERTABLE)*(cInstalledDrivers+1)),
  346. GHND | GMEM_SHARE);
  347. if (!h)
  348. return(0L);
  349. cInstalledDrivers++;
  350. hInstalledDriverList = h;
  351. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  352. /* find an unused entry in the table */
  353. for (index=0;index<cInstalledDrivers;index++)
  354. {
  355. if (lpdt->hModule || lpdt->fBusy)
  356. lpdt++;
  357. else
  358. break;
  359. }
  360. if (index+1 < cInstalledDrivers)
  361. /* The driver went into an unused entry in the middle somewhere so
  362. * restore table size.
  363. */
  364. cInstalledDrivers--;
  365. /* Protect the entry we just allocated so that OpenDriver
  366. * can be called at any point from now on without overriding
  367. * the entry
  368. */
  369. lpdt->fBusy = 1;
  370. h = LoadAliasedLibrary(szDriverName,
  371. szSectionName ? szSectionName : szDrivers,
  372. szSystemIni,
  373. lpstrTail,
  374. cbTail);
  375. if (h < 32)
  376. {
  377. result = MAKELONG(0,h);
  378. goto LoadCleanUp;
  379. }
  380. lpdt->lpDriverEntryPoint = (DRIVERPROC)GetProcAddress(h, szDriverProc);
  381. if (!lpdt->lpDriverEntryPoint)
  382. {
  383. // Driver does not have correct entry point
  384. FreeLibrary(h);
  385. result = 0L;
  386. goto LoadCleanUp;
  387. }
  388. // Set hModule here so that GetDrvrUsage() and DrvSendMessage() work
  389. lpdt->hModule = h;
  390. if (GetDrvrUsage(h) == 1)
  391. {
  392. // First instance of the driver.
  393. if (!DrvSendMessage(index+1, DRV_LOAD, 0L, 0L))
  394. {
  395. // Driver failed load call.
  396. lpdt->lpDriverEntryPoint = NULL;
  397. lpdt->hModule = NULL;
  398. FreeLibrary(h);
  399. result = 0L;
  400. goto LoadCleanUp;
  401. }
  402. lpdt->fFirstEntry = 1;
  403. if (fSendEnable)
  404. DrvSendMessage(index+1, DRV_ENABLE, 0L, 0L);
  405. }
  406. result = MAKELONG(index+1,h);
  407. LoadCleanUp:
  408. lpdt->fBusy = 0;
  409. GlobalUnlock(hInstalledDriverList);
  410. return(result);
  411. }
  412. /***************************************************************************
  413. *
  414. * @doc INTERNAL
  415. *
  416. * @api WORD | InternalFreeDriver | This function decrements the usage
  417. * count of the specified driver. When the driver usage count reaches
  418. * 0, the driver is sent a DRV_FREE message and then freed.
  419. *
  420. * @parm HANDLE | hDriver | Driver handle of the installable driver to be
  421. * freed.
  422. *
  423. * @parm BOOL | fSendDisable | TRUE if a DRV_DISABLE message should be sent
  424. * before the DRV_FREE message if the usage count reaches zero.
  425. *
  426. * @rdesc Returns current driver usage count.
  427. *
  428. * @comm Using LoadLibrary or FreeLibrary directly on a library installed
  429. * with OpenDriver will break this function. A module handle is not
  430. * the same as an installable driver handle.
  431. *
  432. * @xref CloseDriver
  433. *
  434. ***************************************************************************/
  435. WORD FAR PASCAL InternalFreeDriver(WORD hDriver, BOOL fSendDisable)
  436. {
  437. LPDRIVERTABLE lpdt;
  438. HANDLE h;
  439. WORD w;
  440. /* The driver will receive the following message sequence:
  441. *
  442. * if usage count of driver is 1
  443. * DRV_DISABLE (normally)
  444. * DRV_FREE
  445. */
  446. if (hDriver > cInstalledDrivers || !hDriver)
  447. return(0);
  448. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  449. /*
  450. * If the driver usage count is 1, then send
  451. * free and disable messages.
  452. */
  453. /*
  454. Clear dwDriverIdentifier so that the sendmessage for
  455. DRV_OPEN and DRV_ENABLE have dwDriverIdentifier = 0
  456. if an entry gets reused and so that the DRV_DISABLE and DRV_FREE
  457. messages below also get dwDriverIdentifier = 0.
  458. */
  459. lpdt[hDriver-1].dwDriverIdentifier = 0;
  460. w = GetDrvrUsage(lpdt[hDriver-1].hModule);
  461. if (w == 1)
  462. {
  463. if (fSendDisable)
  464. DrvSendMessage(hDriver, DRV_DISABLE, 0L, 0L);
  465. DrvSendMessage(hDriver, DRV_FREE, 0L, 0L);
  466. }
  467. FreeLibrary(lpdt[hDriver-1].hModule);
  468. // Clear the rest of the table entry
  469. lpdt[hDriver-1].hModule = 0; // this indicates free entry
  470. lpdt[hDriver-1].fFirstEntry = 0; // this is also just to be tidy
  471. lpdt[hDriver-1].lpDriverEntryPoint = 0; // this is also just to be tidy
  472. GlobalUnlock(hInstalledDriverList);
  473. return(w-1);
  474. }
  475. #ifdef DEBUG
  476. WORD GetWinVer()
  477. {
  478. WORD w = GetVersion();
  479. return (w>>8) | (w<<8);
  480. }
  481. #endif
  482. void NEAR PASCAL DrvInit(void)
  483. {
  484. HANDLE hlibUser;
  485. LPDRIVERTABLE lpdt;
  486. /* If the window's driver interface is present then use it.
  487. */
  488. DOUT("MMSYSTEM: DrvInit");
  489. hlibUser = GetModuleHandle(szUser);
  490. if(lpOpenDriver = (OPENDRIVER31)GetProcAddress(hlibUser,szOpenDriver))
  491. fUseWinAPI = TRUE;
  492. else
  493. {
  494. fUseWinAPI = FALSE;
  495. DOUT(" - No Windows Driver I/F detected. Using MMSYSTEM\r\n");
  496. //
  497. // force MMSYSTEM into the driver table, without enableing it.
  498. //
  499. cInstalledDrivers = 1;
  500. hInstalledDriverList = GlobalAlloc(GHND|GMEM_SHARE, (DWORD)((WORD)sizeof(DRIVERTABLE)));
  501. #ifdef DEBUG
  502. if (hInstalledDriverList == NULL)
  503. {
  504. DOUT("no memory for driver table\r\n");
  505. FatalExit(-1);
  506. return;
  507. }
  508. #endif
  509. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  510. //
  511. // NOTE! we are not setting fFirstEntry==TRUE
  512. //
  513. // because under windows 3.0 MMSOUND will enable/disable us
  514. // we *dont* wan't the driver interface doing it!
  515. //
  516. lpdt->lpDriverEntryPoint = (DRIVERPROC)DriverProc;
  517. lpdt->hModule = ghInst;
  518. lpdt->fFirstEntry = 0;
  519. GlobalUnlock(hInstalledDriverList);
  520. }
  521. if (fUseWinAPI)
  522. {
  523. DOUT(" - Windows Driver I/F detected\r\n");
  524. #ifdef DEBUG
  525. if (GetWinVer() < 0x30A)
  526. DOUT("MMSYSTEM: WARNING !!! WINDOWS DRIVER I/F BUT VERSION LESS THAN 3.1\r\n");
  527. #endif
  528. // link to the relevant user APIs.
  529. lpCloseDriver = (CLOSEDRIVER31)GetProcAddress(hlibUser, szCloseDriver);
  530. lpGetDriverModuleHandle = (GETDRIVERMODULEHANDLE31)GetProcAddress(hlibUser, szDrvModuleHandle);
  531. lpSendDriverMessage = (SENDDRIVERMESSAGE31)GetProcAddress(hlibUser, szSendDriverMessage);
  532. lpDefDriverProc = (DEFDRIVERPROC31)GetProcAddress(hlibUser, szDefDriverProc);
  533. }
  534. }
  535. /***************************************************************************
  536. *
  537. * @doc INTERNAL
  538. *
  539. * @api void | InternalInstallDriverChain | This function loads the
  540. * drivers specified on the Drivers= line of the [Boot] section
  541. * of system.ini. The Drivers are loaded but not opened.
  542. *
  543. * @rdesc None
  544. *
  545. ***************************************************************************/
  546. void FAR PASCAL InternalInstallDriverChain(void)
  547. {
  548. char szBuffer[150];
  549. BOOL bFinished;
  550. int iStart;
  551. int iEnd;
  552. if (!fUseWinAPI)
  553. {
  554. /* Load DLL's from DRIVERS section in system.ini
  555. */
  556. GetPrivateProfileString(szBoot, /* [Boot] section */
  557. szDrivers, /* Drivers= */
  558. szNull, /* Default if no match */
  559. szBuffer, /* Return buffer */
  560. sizeof(szBuffer),
  561. szSystemIni);
  562. if (!*szBuffer)
  563. return;
  564. bFinished = FALSE;
  565. iStart = 0;
  566. while (!bFinished)
  567. {
  568. iEnd = iStart;
  569. while (szBuffer[iEnd] && (szBuffer[iEnd] != ' ') &&
  570. (szBuffer[iEnd] != ','))
  571. iEnd++;
  572. if (szBuffer[iEnd] == NULL)
  573. bFinished = TRUE;
  574. else
  575. szBuffer[iEnd] = NULL;
  576. /* Load and enable the driver.
  577. */
  578. InternalLoadDriver(&(szBuffer[iStart]), NULL, NULL, 0, TRUE);
  579. iStart = iEnd+1;
  580. }
  581. }
  582. }
  583. /***************************************************************************
  584. *
  585. * @doc INTERNAL
  586. *
  587. * @api void | InternalDriverEnable | This function enables all the
  588. * currently loaded installable drivers. If the user driver i/f
  589. * has been detected, this function will do nothing.
  590. *
  591. * @rdesc None
  592. *
  593. ***************************************************************************/
  594. void FAR PASCAL InternalDriverEnable(void)
  595. {
  596. if (!fUseWinAPI)
  597. InternalBroadcastDriverMessage(1, DRV_ENABLE, 0L, 0L, IBDM_ONEINSTANCEONLY);
  598. }
  599. /***************************************************************************
  600. *
  601. * @doc INTERNAL
  602. *
  603. * @api void | InternalDriverDisable | This function disables all the
  604. * currently loaded installable drivers. If the user driver I/F
  605. * has been detected, this function will do nothing.
  606. *
  607. *
  608. * @rdesc None
  609. *
  610. ***************************************************************************/
  611. void FAR PASCAL InternalDriverDisable(void)
  612. {
  613. if (!fUseWinAPI)
  614. InternalBroadcastDriverMessage(0, DRV_DISABLE, 0L, 0L,
  615. IBDM_ONEINSTANCEONLY | IBDM_REVERSE);
  616. }
  617. /***************************************************************************
  618. *
  619. * @doc INTERNAL
  620. *
  621. * @api HANDLE | LoadAliasedLibrary | This function loads the library module
  622. * contained in the specified file and returns its module handle
  623. * unless the specified name matches a keyname in the
  624. * specified section section of the specified ini file in which case
  625. * the library module in the file specified on the ini line is loaded.
  626. *
  627. * @parm LPSTR | szLibFileName | points to a null-terminated character
  628. * string containing the filename or system.ini keyname.
  629. *
  630. * @parm LPSTR | szSection | points to a null-terminated character
  631. * string containing the section name.
  632. *
  633. * @parm LPSTR | szIniFile | points to a null-terminated character
  634. * string containing the ini filename.
  635. *
  636. * @parm LPSTR | lpstrTail | caller supplied buffer to return the "tail"
  637. * of the system.ini line in. The tail is any characters that follow
  638. * the filename.
  639. *
  640. * @parm WORD | cbTail | size of supplied buffer.
  641. *
  642. * @rdesc Returns the library's module handle.
  643. *
  644. * @xref LoadLibrary
  645. *
  646. ***************************************************************************/
  647. HANDLE FAR PASCAL LoadAliasedLibrary(LPSTR szLibFileName,
  648. LPSTR szSection,
  649. LPSTR szIniFile,
  650. LPSTR lpstrTail,
  651. WORD cbTail)
  652. {
  653. HANDLE h;
  654. char sz[128];
  655. LPSTR pch;
  656. OFSTRUCT of;
  657. if (!szLibFileName || !*szLibFileName)
  658. return(2); // File not found
  659. // read the filename and additional info. into sz
  660. GetPrivateProfileString(szSection, // ini section
  661. szLibFileName, // key name
  662. szLibFileName, // default if no match
  663. sz, // return buffer
  664. sizeof(sz), // return buffer size
  665. szIniFile); // ini. file
  666. sz[sizeof(sz)-1] = 0;
  667. // strip off the additional info.
  668. pch = (LPSTR)sz;
  669. while (*pch)
  670. {
  671. if (*pch == ' ')
  672. {
  673. *pch++ = '\0';
  674. break;
  675. }
  676. pch++;
  677. }
  678. // pch pts to ch after first space or null ch
  679. if (!GetModuleHandle(sz) &&
  680. OpenFile(sz, &of, OF_EXIST|OF_READ|OF_SHARE_DENY_NONE) == -1)
  681. return(2);
  682. // copy additional info. to lpstrTail
  683. if (lpstrTail && cbTail)
  684. {
  685. while (cbTail-- && (*lpstrTail++ = *pch++))
  686. ;
  687. *(lpstrTail-1) = 0;
  688. }
  689. return (LoadLibrary(sz));
  690. }
  691. /***************************************************************************
  692. *
  693. * @doc INTERNAL
  694. *
  695. * @api int | GetDrvrUsage | Runs through the driver list and figures
  696. * out how many instances of this driver module handle we have.
  697. * We use this instead of GetModuleUsage so that we can have drivers
  698. * loaded as normal DLLs and as installable drivers.
  699. *
  700. * @parm HANDLE | h | Driver's module handle
  701. *
  702. * @rdesc Returns the library's driver usage count.
  703. *
  704. ***************************************************************************/
  705. int FAR PASCAL GetDrvrUsage(HANDLE h)
  706. {
  707. LPDRIVERTABLE lpdt;
  708. int index;
  709. int count;
  710. if (!hInstalledDriverList || !cInstalledDrivers)
  711. return(0);
  712. count = 0;
  713. lpdt = (LPDRIVERTABLE)GlobalLock(hInstalledDriverList);
  714. for (index=0;index<cInstalledDrivers;index++)
  715. {
  716. if (lpdt->hModule==h)
  717. {
  718. count++;
  719. }
  720. lpdt++;
  721. }
  722. GlobalUnlock(hInstalledDriverList);
  723. return(count);
  724. }