|
|
1.1 root 1: /****************************************************************************
2: *
3: * registry.c
4: *
5: * Copyright (c) 1992 Microsoft Corporation. All Rights Reserved.
6: *
7: * This file contains functions to maintain registry entries for
8: * kernel drivers installed via the drivers control panel applet.
9: *
10: * Note that the ONLY state maintained between calls here is whatever
11: * state the registry and its handles maintain.
12: *
13: * The registry entries are structured as follows :
14: * (see also winreg.h, winnt.h)
15: *
16: * HKEY_LOCAL_MACHINE
17: * SYSTEM
18: * CurrentControlSet
19: * Services
20: * DriverNode (eg sndblst)
21: * Type = SERVICE_KERNEL_DRIVER (eg)
22: * Group = "Base"
23: * ErrorControl = SERVICE_ERROR_NORMAL
24: * Start = SERVICE_SYSTEM_START |
25: * SERVICE_DEMAND_START |
26: * SERVICE_DISABLED
27: * ...
28: * Tag = A unique number ???
29: *
30: * Device
31: * Interrupt =
32: * Port =
33: * DMAChannel =
34: *
35: * The Driver node is set up by the services manager when we call
36: * CreateService but we have to insert the device data ourselves.
37: *
38: *
39: *
40: * The registry entries are shared between :
41: *
42: * The system loader (which uses the Services entry)
43: * The kernel driver (which reads from the Device entry)
44: * This component called from the drivers control panel applet
45: * The service control manager
46: * The Setup utility
47: *
48: * Security access
49: * ---------------
50: *
51: * The driver determines whether it can perform configuration and
52: * installation by whether it can get read and write access to the
53: * service control manager. This is required to manipulate the kernel
54: * driver database.
55: *
56: * Services controller
57: * -------------------
58: *
59: * The services controller is used because this is the only way we
60: * are allowed to load and unload kernel drivers. Only the services
61: * controller can call LoadDriver and UnloadDriver and not get 'access
62: * denied'.
63: *
64: * Note also that we can't keep the services controller handle open
65: * at the same time as the registry handle because then we can't get
66: * write access (actually we only need KEY_CREATE_SUB_KEY access) to
67: * our device parameters subkey.
68: *
69: ***************************************************************************/
70:
71: #include <stdio.h>
72: #ifdef UNICODE
73: #include <wchar.h>
74: #else
75: #include <string.h>
76: #define wcscat strcat
77: #define wcscpy strcpy
78: #define wcsicmp stricmp
79: #endif
80: #include <windows.h>
81: #include <mmsystem.h>
82: #include <winsvc.h>
83: #include <soundcfg.h>
84: #include "registry.h"
85:
86: /***************************************************************************
87: *
88: * Constants for accessing the registry
89: *
90: ***************************************************************************/
91:
92: /*
93: * Path to service node key
94: */
95:
96: #define STR_SERVICES_NODE TEXT("SYSTEM\\CurrentControlSet\\Services\\")
97:
98: /*
99: * Node sub-key for device parameters
100: */
101:
102: #define STR_DEVICE_DATA PARMS_SUBKEY
103:
104: /*
105: * Name of Base group where sound drivers normally go
106: */
107:
108: #define STR_BASE_GROUP TEXT("Base")
109:
110: /*
111: * Name of driver group for synthesizers
112: * - we use our own name here to make sure
113: * we are loaded after things like the PAS driver. (Base is a
114: * known group and drivers in it are always loaded before unknown
115: * groups like this one).
116: */
117:
118: #define STR_SYNTH_GROUP TEXT("Synthesizer Drivers")
119:
120: /*
121: * Name of service
122: */
123:
124: #define STR_DRIVER TEXT("\\Driver\\")
125:
126: /*
127: * Path to kernel drivers directory from system directory
128: */
129:
130: #define STR_DRIVERS_DIR TEXT("\\SystemRoot\\SYSTEM32\\DRIVERS\\")
131:
132: /*
133: * Extension for drivers
134: */
135:
136: #define STR_SYS_EXT TEXT(".SYS")
137:
138:
139: HKEY DrvOpenRegKey(LPTSTR DriverName)
140: {
141: TCHAR RegistryPath[MAX_PATH];
142: HKEY NodeHandle;
143:
144: //
145: // Create the path to our node
146: //
147:
148: wcscpy(RegistryPath, STR_SERVICES_NODE);
149: wcscat(RegistryPath, DriverName);
150:
151: //
152: // See if we can get a registry handle to our device data
153: //
154:
155:
156: if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
157: RegistryPath,
158: 0L,
159: KEY_ALL_ACCESS,
160: &NodeHandle)
161: != ERROR_SUCCESS) {
162: return NULL;
163: } else {
164: return NodeHandle;
165: }
166: }
167:
168:
169: SC_HANDLE DrvOpenService(PREG_ACCESS RegAccess)
170: {
171: SC_HANDLE Handle;
172: Handle = OpenService(RegAccess->ServiceManagerHandle,
173: RegAccess->DriverName,
174: SERVICE_ALL_ACCESS);
175:
176: #if 0
177: if (Handle == NULL) {
178: char buf[100];
179: sprintf(buf, "OpenService failed code %d\n", GetLastError());
180: OutputDebugStringA(buf);
181: }
182: #endif
183:
184: return Handle;
185: }
186:
187: void DrvCloseService(PREG_ACCESS RegAccess, SC_HANDLE ServiceHandle)
188: {
189: CloseServiceHandle(ServiceHandle);
190: }
191:
192: /***************************************************************************
193: *
194: * Function :
195: * DrvCreateServicesNode
196: *
197: * Parameters :
198: * DriverNodeName The name of the service node. Same as the
199: * name of the driver which must be
200: * DriverNodeName.sys for the system to find it.
201: *
202: * DriverType Type of driver - see registry.h
203: *
204: * ServiceNodeKey Pointer to where to put returned handle
205: *
206: * Return code :
207: *
208: * Standard error code (see winerror.h)
209: *
210: * Description :
211: *
212: * Create the service node key
213: *
214: * The class name of the registry node is ""
215: *
216: ***************************************************************************/
217:
218: BOOL
219: DrvCreateServicesNode(LPTSTR DriverName,
220: SOUND_KERNEL_MODE_DRIVER_TYPE DriverType,
221: PREG_ACCESS RegAccess,
222: BOOL Create)
223: {
224: SERVICE_STATUS ServiceStatus;
225: SC_HANDLE ServiceHandle; // Handle to our driver 'service'
226:
227: RegAccess->DriverName = DriverName;
228:
229: //
230: // See if we can open the registry
231: //
232:
233: if (RegAccess->ServiceManagerHandle == NULL) {
234: RegAccess->ServiceManagerHandle =
235: OpenSCManager(
236: NULL, // This machine
237: NULL, // The active database
238: SC_MANAGER_ALL_ACCESS); // We want to create and change
239:
240: if (RegAccess->ServiceManagerHandle == NULL) {
241: return FALSE;
242: }
243: }
244:
245: //
246: // Open our particular service
247: //
248:
249: ServiceHandle = DrvOpenService(RegAccess);
250:
251: //
252: // See if that worked
253: //
254:
255: if (ServiceHandle == NULL &&
256: GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) {
257: if (Create) {
258: SC_LOCK ServicesDatabaseLock;
259: TCHAR ServiceName[MAX_PATH];
260: TCHAR BinaryPath[MAX_PATH];
261:
262: wcscpy(BinaryPath, STR_DRIVERS_DIR);
263: wcscat(BinaryPath, DriverName);
264: wcscat(BinaryPath, STR_SYS_EXT);
265:
266: wcscpy(ServiceName, STR_DRIVER);
267: wcscat(ServiceName, DriverName);
268:
269: /*
270: * Lock the service controller database to avoid deadlocks
271: * we have to loop because we can't wait
272: */
273:
274:
275: for (ServicesDatabaseLock = NULL;
276: (ServicesDatabaseLock =
277: LockServiceDatabase(RegAccess->ServiceManagerHandle))
278: == NULL;
279: Sleep(100)) {
280: }
281:
282:
283: /*
284: * Create the service
285: */
286:
287:
288: ServiceHandle =
289: CreateService(
290: RegAccess->ServiceManagerHandle,
291: DriverName, // Service name
292: NULL, // ???
293: SERVICE_ALL_ACCESS, // Full access
294: SERVICE_KERNEL_DRIVER, // Kernel driver
295: SERVICE_DEMAND_START, // Start at sys start
296: SERVICE_ERROR_NORMAL, // Not a disaster if fails
297: BinaryPath, // Default path
298:
299: DriverType == SoundDriverTypeSynth ?
300: STR_SYNTH_GROUP : // Driver group
301: STR_BASE_GROUP,
302: NULL, // do not want TAG information
303: TEXT("\0"), // No dependencies
304: NULL, // ServiceName, // Driver object - optional
305: NULL); // No password
306:
307: UnlockServiceDatabase(ServicesDatabaseLock);
308: #if DBG
309: if (ServiceHandle == NULL) {
310: TCHAR buf[100];
311: wsprintf(buf, TEXT("CreateService failed code %d\n"), GetLastError());
312: OutputDebugString(buf);
313: }
314: #endif
315:
316: }
317: }
318:
319: //
320: // Check at least that it's a device driver
321: //
322:
323: if (ServiceHandle != NULL) {
324: if (!QueryServiceStatus(
325: ServiceHandle,
326: &ServiceStatus) ||
327: ServiceStatus.dwServiceType != SERVICE_KERNEL_DRIVER) {
328:
329: //
330: // Doesn't look like ours
331: //
332:
333: CloseServiceHandle(RegAccess->ServiceManagerHandle);
334: RegAccess->ServiceManagerHandle = NULL;
335: DrvCloseService(RegAccess, ServiceHandle);
336: return FALSE;
337: }
338:
339: }
340:
341: if (ServiceHandle == NULL) {
342: //
343: // Leave the SC manager handle open. We use the presence of this
344: // handle to test whether the driver can be configured (ie whether we
345: // have the access rights to get into the SC manager).
346: //
347:
348: return FALSE;
349: } else {
350: //
351: // We can't keep this handle open (even though we'd like to) because
352: // we need write access to the registry node created so that
353: // we can add device parameters
354: //
355:
356: DrvCloseService(RegAccess, ServiceHandle);
357: return TRUE;
358: }
359: }
360:
361:
362: /***************************************************************************
363: *
364: * Function :
365: * DrvCloseServicesNode
366: *
367: * Parameters :
368: * ServiceNodeKey
369: *
370: * Return code :
371: *
372: * Standard error code (see winerror.h)
373: *
374: * Description :
375: *
376: * Close our handle
377: *
378: ***************************************************************************/
379:
380: VOID
381: DrvCloseServiceManager(
382: PREG_ACCESS RegAccess)
383: {
384: if (RegAccess->ServiceManagerHandle != NULL) {
385: CloseServiceHandle(RegAccess->ServiceManagerHandle);
386: RegAccess->ServiceManagerHandle = NULL;
387: }
388: }
389:
390: /***************************************************************************
391: *
392: * Function :
393: * DrvDeleteServicesNode
394: *
395: * Parameters :
396: * DeviceName
397: *
398: * Return code :
399: *
400: * TRUE = success, FALSE = failed
401: *
402: * Description :
403: *
404: * Delete our node using the handle proviced
405: *
406: ***************************************************************************/
407:
408: BOOL
409: DrvDeleteServicesNode(
410: PREG_ACCESS RegAccess)
411: {
412: BOOL Success;
413: SC_LOCK ServicesDatabaseLock;
414: SC_HANDLE ServiceHandle;
415: HKEY NodeHandle;
416:
417: NodeHandle = DrvOpenRegKey(RegAccess->DriverName);
418:
419: //
420: // Make sure we're not accessing the registry ourselves and
421: // that there aren't any subkeys
422: //
423:
424: if (NodeHandle) {
425: RegDeleteKey(NodeHandle, STR_DEVICE_DATA);
426: RegFlushKey(NodeHandle);
427: RegCloseKey(NodeHandle);
428: }
429:
430: //
431: // Delete the service node and free tha handle
432: // (Note the service cannot be deleted until all handles are closed)
433: //
434:
435: ServiceHandle = DrvOpenService(RegAccess);
436:
437: if (ServiceHandle == NULL) {
438: LONG Error;
439: Error = GetLastError();
440: if (Error == ERROR_SERVICE_DOES_NOT_EXIST) {
441: //
442: // It's already gone !
443: //
444: return TRUE;
445: } else {
446: return FALSE; // It was there but something went wrong
447: }
448: }
449:
450: /*
451: * Lock the service controller database to avoid deadlocks
452: * we have to loop because we can't wait
453: */
454:
455:
456: for (ServicesDatabaseLock = NULL;
457: (ServicesDatabaseLock =
458: LockServiceDatabase(RegAccess->ServiceManagerHandle))
459: == NULL;
460: Sleep(100)) {
461: }
462:
463: Success = DeleteService(ServiceHandle);
464:
465: UnlockServiceDatabase(ServicesDatabaseLock);
466:
467: DrvCloseService(RegAccess, ServiceHandle);
468:
469: return Success;
470: }
471:
472:
473: /***************************************************************************
474: *
475: * Function :
476: * DrvSetDeviceParameter
477: *
478: * Parameters :
479: * ServiceNodeKey Handle to the device services node key
480: * ValueName Name of value to set
481: * Value DWORD value to set
482: *
483: * Return code :
484: *
485: * Standard error code (see winerror.h)
486: *
487: * Description :
488: *
489: * Add the value to the device parameters section under the
490: * services node.
491: * This section is created if it does not already exist.
492: *
493: ***************************************************************************/
494:
495: LONG
496: DrvSetDeviceParameter(
497: PREG_ACCESS RegAccess,
498: LPTSTR ValueName,
499: DWORD Value)
500: {
501: HKEY ServiceNodeKey;
502: HKEY ParmsKey;
503: LONG ReturnCode;
504:
505: ServiceNodeKey = DrvOpenRegKey(RegAccess->DriverName);
506:
507: if (ServiceNodeKey == NULL) {
508: return ERROR_FILE_NOT_FOUND;
509: }
510:
511: //
512: // First try to get a handle to the parameters subkey - which may
513: // involve creating the subkey
514: //
515:
516: ReturnCode = RegCreateKey(ServiceNodeKey, STR_DEVICE_DATA, &ParmsKey);
517:
518: RegCloseKey(ServiceNodeKey);
519:
520: if (ReturnCode != ERROR_SUCCESS) {
521: return ReturnCode;
522: }
523:
524: //
525: // Write the value
526: //
527:
528:
529: ReturnCode = RegSetValueEx(ParmsKey, // Registry handle
530: ValueName, // Name of item
531: 0, // Reserved 0
532: REG_DWORD, // Data type
533: (LPBYTE)&Value, // The value
534: sizeof(Value)); // Data length
535:
536: //
537: // Free the handles we created
538: //
539:
540: RegCloseKey(ParmsKey);
541:
542: return ReturnCode;
543: }
544:
545: /***************************************************************************
546: *
547: * Function :
548: * DrvCreateParamsKey
549: *
550: * Parameters :
551: * RegAccess Registry access info
552: *
553: * Return code :
554: *
555: * Standard error code (see winerror.h)
556: *
557: * Description :
558: *
559: * Create the device parameters section under the
560: * services node if it does not already exist. No values are
561: * written to the key.
562: *
563: ***************************************************************************/
564:
565: LONG
566: DrvCreateParamsKey(
567: PREG_ACCESS RegAccess)
568: {
569: HKEY ServiceNodeKey;
570: HKEY ParmsKey;
571: LONG ReturnCode;
572:
573: ServiceNodeKey = DrvOpenRegKey(RegAccess->DriverName);
574:
575: if (ServiceNodeKey == NULL) {
576: return ERROR_FILE_NOT_FOUND;
577: }
578:
579: //
580: // Try to get a handle to the parameters subkey - which may
581: // involve creating the subkey
582: //
583:
584: ReturnCode = RegCreateKey(ServiceNodeKey, STR_DEVICE_DATA, &ParmsKey);
585:
586: RegCloseKey(ServiceNodeKey);
587:
588: if (ReturnCode == ERROR_SUCCESS) {
589: RegCloseKey(ParmsKey);
590: }
591:
592: return ReturnCode;
593:
594: }
595:
596: /***************************************************************************
597: *
598: * Function :
599: * DrvQueryDeviceParameter
600: *
601: * Parameters :
602: * ServiceNodeKey Handle to the device services node key
603: * ValueName Name of value to query
604: * pValue Returned value
605: *
606: * Return code :
607: *
608: * Standard error code (see winerror.h)
609: *
610: * Description :
611: *
612: * Add the value to the device parameters section under the
613: * services node.
614: * This section is created if it does not already exist.
615: *
616: ***************************************************************************/
617:
618: LONG
619: DrvQueryDeviceParameter(
620: PREG_ACCESS RegAccess,
621: LPTSTR ValueName,
622: PDWORD pValue)
623: {
624: HKEY ServiceNodeKey;
625: HKEY ParmsKey;
626: LONG ReturnCode;
627: DWORD Index;
628:
629: ServiceNodeKey = DrvOpenRegKey(RegAccess->DriverName);
630:
631: if (ServiceNodeKey == NULL) {
632: return ERROR_FILE_NOT_FOUND;
633: }
634:
635: //
636: // First try to get a handle to the parameters subkey
637: //
638:
639: ReturnCode = RegOpenKey(ServiceNodeKey, STR_DEVICE_DATA, &ParmsKey);
640: RegCloseKey(ServiceNodeKey);
641:
642: if (ReturnCode != ERROR_SUCCESS) {
643: return ReturnCode;
644: }
645:
646: //
647: // That was OK
648: // Now we have to laboriously search the key values to
649: // see if one corresponds to the one we want
650: //
651:
652:
653: for (Index = 0; ; Index++) { // Enumerate key values
654:
655: TCHAR ThisValueName[MAX_PATH];
656: DWORD NameLength;
657: DWORD Type;
658: DWORD Value;
659: DWORD ValueLength;
660:
661: NameLength = MAX_PATH;
662: NameLength = sizeof(ThisValueName);
663: ValueLength = sizeof(Value);
664:
665: ReturnCode = RegEnumValue(ParmsKey, // Handle to key
666: Index, // Index of value
667: ThisValueName, // Where to put the name
668: &NameLength, // Length of the name
669: NULL, // Reserved NULL
670: &Type, // returns REG_... type
671: (LPBYTE)&Value, // Where to put the value
672: &ValueLength); // Max length of data
673:
674: if (ReturnCode == ERROR_SUCCESS) {
675: //
676: // We've found something - does it's name match the
677: // name we're looking for ?
678: //
679:
680: if (0 == wcsicmp(ValueName, ThisValueName)) {
681: RegCloseKey(ParmsKey);
682:
683: //
684: // If it's the wrong type there's something
685: // wrong !!
686: //
687:
688: if (Type == REG_DWORD) {
689:
690: //
691: // Return Value to caller
692: //
693:
694: *pValue = Value;
695: return ERROR_SUCCESS;
696: } else {
697: return ERROR_FILE_NOT_FOUND;
698: }
699: }
700: } else {
701: //
702: // We didn't find the value with the name we were
703: // looking for so return the default
704: //
705:
706: RegCloseKey(ParmsKey);
707: return ReturnCode;
708: }
709: }
710: }
711:
712:
713: /***************************************************************************
714: *
715: * Function :
716: * DrvLoadKernelDriver
717: *
718: * Parameters :
719: * Drivername Name of driver to load
720: *
721: * Return code :
722: *
723: * TRUE if successful, otherwise FALSE
724: *
725: * Description :
726: *
727: * Call StartService to load the driver. This assumes the services
728: * name is the driver name
729: *
730: ***************************************************************************/
731:
732: BOOL
733: DrvLoadKernelDriver(
734: PREG_ACCESS RegAccess)
735: {
736: SC_HANDLE ServiceHandle;
737: BOOL Success;
738: ServiceHandle = DrvOpenService(RegAccess);
739:
740: if (ServiceHandle == NULL) {
741: return FALSE;
742: }
743:
744: /*
745: * StartService causes the system to try to load the kernel driver
746: */
747:
748: Success = StartService(ServiceHandle, 0, NULL);
749:
750: /*
751: * If this was successful we can change the start type to system
752: * start
753: */
754:
755: if (Success) {
756: Success = ChangeServiceConfig(ServiceHandle,
757: SERVICE_NO_CHANGE,
758: SERVICE_SYSTEM_START,
759: SERVICE_NO_CHANGE,
760: NULL,
761: NULL,
762: NULL,
763: NULL,
764: NULL,
765: NULL,
766: NULL);
767: }
768: DrvCloseService(RegAccess, ServiceHandle);
769: return Success;
770: }
771:
772: /***************************************************************************
773: *
774: * Function :
775: * DrvUnLoadKernelDriver
776: *
777: * Parameters :
778: * RegAccess Access variables to registry and Service control
779: * manager
780: *
781: * Return code :
782: *
783: * TRUE if successful, otherwise FALSE
784: *
785: * Description :
786: *
787: * Call ControlService to unload the driver. This assumes the services
788: * name is the driver name
789: *
790: ***************************************************************************/
791:
792: BOOL
793: DrvUnloadKernelDriver(
794: PREG_ACCESS RegAccess)
795: {
796: SERVICE_STATUS ServiceStatus;
797: SC_HANDLE ServiceHandle;
798: BOOL Success;
799:
800:
801: ServiceHandle = DrvOpenService(RegAccess);
802: if (ServiceHandle == NULL) {
803: return GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST;
804: }
805:
806: /*
807: * Set it not to load at system start until we've reconfigured
808: */
809:
810: Success = ChangeServiceConfig(ServiceHandle,
811: SERVICE_NO_CHANGE,
812: SERVICE_DEMAND_START,
813: SERVICE_NO_CHANGE,
814: NULL,
815: NULL,
816: NULL,
817: NULL,
818: NULL,
819: NULL,
820: NULL);
821:
822: if (Success) {
823: /*
824: * Don't try to unload if it's not loaded
825: */
826:
827: if (DrvIsDriverLoaded(RegAccess)) {
828:
829: /*
830: * Note that the driver object name will not be found if
831: * the driver is not loaded. However, the services manager may
832: * get in first and decide that the driver file does not exist.
833: */
834:
835: Success = ControlService(ServiceHandle,
836: SERVICE_CONTROL_STOP,
837: &ServiceStatus);
838:
839: }
840:
841: }
842:
843: DrvCloseService(RegAccess, ServiceHandle);
844: return Success;
845: }
846:
847: /***************************************************************************
848: *
849: * Function :
850: *
851: * DrvIsDriverLoaded
852: *
853: * Parameters :
854: *
855: * RegAccess Access variables to registry and Service control
856: * manager
857: *
858: * Return code :
859: *
860: * TRUE if successful, otherwise FALSE
861: *
862: * Description :
863: *
864: * See if a service by our name is started.
865: * Note - this assumes that we think our service is installed
866: *
867: ***************************************************************************/
868: BOOL
869: DrvIsDriverLoaded(
870: PREG_ACCESS RegAccess)
871: {
872: SERVICE_STATUS ServiceStatus;
873: SC_HANDLE ServiceHandle;
874: BOOL Success;
875: ServiceHandle = DrvOpenService(RegAccess);
876: if (ServiceHandle == NULL) {
877: return FALSE;
878: }
879:
880:
881: if (!QueryServiceStatus(ServiceHandle, &ServiceStatus)) {
882: DrvCloseService(RegAccess, ServiceHandle);
883: return FALSE;
884: }
885:
886: Success = ServiceStatus.dwServiceType == SERVICE_KERNEL_DRIVER &&
887: ServiceStatus.dwCurrentState == SERVICE_RUNNING;
888:
889: DrvCloseService(RegAccess, ServiceHandle);
890: return Success;
891: }
892:
893:
894: /***************************************************************************
895: *
896: * Function :
897: *
898: * DrvConfigureDriver
899: *
900: * Parameters :
901: *
902: * RegAccess Access variables to registry and Service control
903: * manager
904: *
905: * DriverName Name of the driver
906: *
907: * DriverType Type of driver (see registry.h)
908: *
909: * SetParms Callback to set the registry parameters
910: *
911: * Context Context value for callback
912: *
913: * Return code :
914: *
915: * TRUE if successful, otherwise FALSE
916: *
917: * Description :
918: *
919: * Performs the necessary operations to (re) configure a driver :
920: *
921: * 1. If the driver is already installed :
922: *
923: * Unload it if necessary
924: *
925: * Set its start type to Demand until we know we're safe
926: * (This is so the system won't load a bad config if we crash)
927: *
928: * 2. If the driver is not installed create its service entry in the
929: * registry.
930: *
931: * 3. Run the callback to set up the driver's parameters
932: *
933: * 4. Load the driver
934: *
935: * 5. If the load returns success set the start type to System start
936: *
937: ***************************************************************************/
938:
939: BOOL DrvConfigureDriver(
940: PREG_ACCESS RegAccess,
941: LPTSTR DriverName,
942: SOUND_KERNEL_MODE_DRIVER_TYPE
943: DriverType,
944: BOOL (* SetParms )(PVOID),
945: PVOID Context)
946: {
947: return
948:
949: /*
950: * If there isn't a services node create one - this is done first
951: * because this is how the driver name gets into the REG_ACCESS
952: * structure
953: */
954:
955: DrvCreateServicesNode(
956: DriverName,
957: DriverType,
958: RegAccess,
959: TRUE)
960:
961: &&
962:
963: /*
964: * Unload driver if it's loaded
965: */
966:
967: DrvUnloadKernelDriver(RegAccess)
968:
969: &&
970:
971: /*
972: * Run the callback
973: */
974:
975: (SetParms == NULL || (*SetParms)(Context))
976:
977: &&
978:
979: /*
980: * Try reloading the driver
981: */
982:
983: DrvLoadKernelDriver(RegAccess)
984:
985: ;
986:
987: }
988:
989:
990: /***************************************************************************
991: *
992: * Function :
993: *
994: * DrvRemoveDriver
995: *
996: * Parameters :
997: *
998: * RegAccess Access variables to registry and Service control
999: * manager
1000: *
1001: * Return code :
1002: *
1003: * DRVCNF_CANCEL - Error occurred
1004: *
1005: * DRVCNF_OK - Registry entry delete but driver wasn't loaded
1006: *
1007: * DRVCNF_RESTART - Driver unloaded and registry entry deleted
1008: *
1009: * Description :
1010: *
1011: * Unload the driver and remove its service control entry
1012: *
1013: ***************************************************************************/
1014:
1015: LRESULT DrvRemoveDriver(
1016: PREG_ACCESS RegAccess)
1017: {
1018: BOOL Loaded;
1019:
1020: Loaded = DrvIsDriverLoaded(RegAccess);
1021:
1022: if ((!Loaded || DrvUnloadKernelDriver(RegAccess)) &&
1023: DrvDeleteServicesNode(RegAccess)) {
1024: return Loaded ? DRVCNF_RESTART : DRVCNF_OK;
1025: } else {
1026: return DRVCNF_CANCEL;
1027: }
1028: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.