Annotation of ntddk/src/mmedia/synth/dll/registry.c, revision 1.1

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:  }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.