home *** CD-ROM | disk | FTP | other *** search
- //
- // This program installs the PROCSRV.exe into the Service Control Manager. It also
- // adds a service entry to the SQL Service Manager.
- // The service name "ProcSrv" will be added to the registry under the tree
- // "\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SQLServer\"
- //
- // Copyright 1994, Microsoft.
- //
-
- #include <windows.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define PROCSRV "ProcSrv"
- #define PROCSRV_KEY_PATH "SOFTWARE\\Microsoft\\MSSQLServer\\ProcSrv\\"
- #define SQL_SM_KEY "SOFTWARE\\Microsoft\\MSSQLServer\\SQL Service Manager\\"
-
- #define NAMED_PIPE_DLL "SSNMPN60"
- #define NAMED_PIPE_ADDRESS "\\\\.\\pipe\\sql\\query"
- #define TCP_IP_DLL "SSMSSO60"
- #define TCP_ADDRESS "1433"
-
- void AddToRegistry();
- void RemoveFromRegistry();
- BOOL DuplicateEntry();
- void RefreshStoplight();
-
- void main( int argc, char ** argv )
- {
- if( argc != 2 )
- goto Usage;
-
- if( !stricmp("add", argv[1]) )
- AddToRegistry();
- else if( !stricmp("remove", argv[1]) )
- RemoveFromRegistry();
- else
- goto Usage;
-
- RefreshStoplight();
- return;
-
- Usage:
- printf( "Usage: service {add|remove}\n"
- " where \"add\" adds ProcSrv and \"remove\" removes it\n" );
- }
-
-
- // **************************************************************************
- //
- // FUNCTION: AddToRegistry()
- //
- // PURPOSE: Add ProcSrv to Registry and Service Control Manager
- //
- // **************************************************************************
-
- void AddToRegistry()
- {
- int i;
- HKEY hKey;
- HKEY hKeySM;
- DWORD dwDisposition;
- DWORD dwSize = 0;
- DWORD dwSizeSM;
- DWORD dwType;
- DWORD dwPathLength;
- char szPath[1024];
- char szSMvalues[1024];
- char szSaveListenOn[1024];
- char * szSaveListenOnPos = szSaveListenOn;
-
- SC_HANDLE hSCM; // Handle to opened Service Control Manager
- SC_LOCK LockSCM; // Lock of Service Control Manager
- SC_HANDLE hSrvc; // Handle to service
-
- // Check for existance of "ProcSrv" in registry
- //
- if( DuplicateEntry() )
- {
- printf( "Duplicate entry 'ProcSrv' found in Registry, remove 'ProcSrv' from Registry\n" );
- return;
- }
-
- // ======== Update SQL Service Manager info ===========
- //
- if( RegCreateKeyEx(HKEY_LOCAL_MACHINE,
- SQL_SM_KEY,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKeySM,
- &dwDisposition)
- != ERROR_SUCCESS )
- goto AddExit2;
-
- dwSizeSM = sizeof( szSMvalues );
-
- // Get list of SQL Service Manager entries
- //
- if( RegQueryValueEx(hKeySM,
- "Services",
- NULL,
- &dwType,
- szSMvalues,
- &dwSizeSM)
- != ERROR_SUCCESS )
- {
- dwSizeSM = 1;
- szSMvalues[0] = '\0';
- }
-
- if( (dwSizeSM+strlen(PROCSRV)+1) < sizeof(szSMvalues) )
- {
- // Append new value to list of SQL Service Manager entries.
- //
- memcpy( (szSMvalues+dwSizeSM-1),
- PROCSRV,
- (strlen(PROCSRV)+1) );
- dwSizeSM += strlen(PROCSRV);
- szSMvalues[dwSizeSM] = '\0';
- dwSizeSM++;
- }
-
- // Note that we delay write of new values to Stoplight Registry entry.
- // First well will try to update the Service Control Manager.
-
- // ==== Write entry to Service Control Manager ====
- //
- hSCM = OpenSCManager( NULL,
- "ServicesActive",
- SC_MANAGER_ALL_ACCESS );
- if( hSCM == NULL )
- goto AddExit4;
-
- i = 0;
- while( TRUE )
- {
- LockSCM = LockServiceDatabase( hSCM );
-
- if( LockSCM != NULL )
- break;
-
- if( i++ >= 5 )
- goto AddExit3; // Can't lock database
-
- Sleep( 1000 ); // sleep for a second
- }
-
- // Get the path of this process. We'll use it to constuct the path of the
- // ProcSrv.exe
- //
- szPath[0] = '\0';
- dwPathLength = GetModuleFileName( GetModuleHandle(NULL), szPath, sizeof(szPath) );
-
- // Stip off process name (i.e. "service.exe")
- //
- while( dwPathLength > 1 )
- {
- --dwPathLength;
- if( szPath[dwPathLength] == '\\' || szPath[dwPathLength] == ':' )
- {
- dwPathLength++;
- szPath[dwPathLength] = '\0'; // Null terminate after the back slash
- break;
- }
- }
-
- // Append "procsrv.exe" to path
- //
- strcat( szPath, PROCSRV );
- strcat( szPath, ".exe" );
-
- // Let's create the service entry
- //
- hSrvc = CreateService( hSCM,
- PROCSRV, // Service name to start
- PROCSRV, // Display name
- SERVICE_ALL_ACCESS,
- SERVICE_WIN32_OWN_PROCESS,
- SERVICE_DEMAND_START,
- SERVICE_ERROR_NORMAL,
- szPath,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL );
- if( hSrvc == NULL )
- goto AddExit3;
-
- CloseServiceHandle( hSrvc );
- UnlockServiceDatabase( LockSCM );
- CloseServiceHandle( hSCM );
-
- // Now we'll update Registry with new ProcSrv entry
- //
- if( RegCreateKeyEx(HKEY_LOCAL_MACHINE,
- PROCSRV_KEY_PATH,
- 0,
- NULL,
- REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
- NULL,
- &hKey,
- &dwDisposition)
- != ERROR_SUCCESS )
- goto AddExit2;
-
- // ==== Update ListenOn ====
- //
- strcpy( szSaveListenOnPos, NAMED_PIPE_DLL );
- strcat( szSaveListenOnPos, "," );
- strcat( szSaveListenOnPos, NAMED_PIPE_ADDRESS );
-
- dwSize += (strlen(szSaveListenOnPos) + 1);
- szSaveListenOnPos = szSaveListenOn + dwSize;
-
- strcpy( szSaveListenOnPos, TCP_IP_DLL );
- strcat( szSaveListenOnPos, "," );
- strcat( szSaveListenOnPos, TCP_ADDRESS );
-
-
- dwSize += (strlen(szSaveListenOnPos) + 1);
- szSaveListenOnPos = szSaveListenOn + dwSize;
-
- szSaveListenOn[dwSize] = '\0';
- dwSize++;
-
- if( RegSetValueEx(hKey,
- "ListenOn",
- 0,
- REG_MULTI_SZ,
- szSaveListenOn,
- dwSize)
- != ERROR_SUCCESS )
- goto AddExit1;
-
- // ==== Complete the update of the SQL Service Manager info ============
- // We do it here to avoid a duplicate entry if other registry updates
- // fail.
- //
- if( RegSetValueEx(hKeySM,
- "Services",
- 0,
- REG_MULTI_SZ,
- szSMvalues,
- dwSizeSM)
- != ERROR_SUCCESS )
- {
- RegCloseKey( hKeySM );
- goto AddExit1;
- }
-
- RegFlushKey( hKeySM );
- RegCloseKey( hKeySM );
-
- return;
-
- AddExit1:
- RegCloseKey( hKey );
-
- AddExit2:
- printf( "Unable to Update Registry\n" );
- return;
-
- AddExit3:
- UnlockServiceDatabase( LockSCM );
- CloseServiceHandle( hSCM );
-
- AddExit4:
- printf( "Unable to Update Service Control Manager\n" );
- return;
- }
-
-
- // **************************************************************************
- //
- // FUNCTION: RemoveFromRegistry()
- //
- // PURPOSE: Remove ProcSrv From Registry and Service Control Manager
- //
- // **************************************************************************
-
- void RemoveFromRegistry()
- {
- int i;
- HKEY hKey;
- DWORD dwSizeSM;
- DWORD dwType;
- char szSMvalues[1024];
- char * szSMvaluesPos;
-
- SC_HANDLE hSCM; // Handle to opened Service Control Manager
- SC_LOCK LockSCM; // Lock of Service Control Manager
- SC_HANDLE hSrvc; // Handle to service
-
- // Check for non-existance of "ProcSrv" in registry
- //
- if( !DuplicateEntry() )
- {
- printf( "'ProcSrv' not found in Registry\n" );
- return;
- }
-
- // =============== Remove 'ProcSrv' key from Registry =============
- //
- RegDeleteKey( HKEY_LOCAL_MACHINE, PROCSRV_KEY_PATH );
-
- // =============== Update SQL Service Manager info ================
- //
- if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- SQL_SM_KEY,
- 0,
- KEY_ALL_ACCESS,
- &hKey)
- != ERROR_SUCCESS )
- goto RemoveExit2;
-
- dwSizeSM = sizeof( szSMvalues );
-
- // Get SQL Service Manager entries
- //
- if( RegQueryValueEx(hKey,
- "Services",
- NULL,
- &dwType,
- szSMvalues,
- &dwSizeSM)
- != ERROR_SUCCESS )
- goto RemoveExit1; // No SQL Service Manager entries.
-
- szSMvaluesPos = szSMvalues;
-
- while( szSMvaluesPos < (szSMvalues + dwSizeSM) )
- {
- if( !stricmp(szSMvaluesPos, PROCSRV) )
- {
- // Remove 'ProcSrv' from SQL Service Manager entries.
- //
- memcpy( szSMvaluesPos,
- szSMvaluesPos + sizeof(PROCSRV),
- ((szSMvalues + dwSizeSM) - (szSMvaluesPos + sizeof(PROCSRV))) );
-
- dwSizeSM -= sizeof( PROCSRV );
- break;
- }
-
- // 'ProcSrv' entry not found, position to next entry.
- //
- szSMvaluesPos += (strlen( szSMvaluesPos ) + 1);
- }
-
- // Write back out new list of SQL Service Manager entries.
- //
- if( RegSetValueEx(hKey,
- "Services",
- 0,
- REG_MULTI_SZ,
- szSMvalues,
- dwSizeSM)
- != ERROR_SUCCESS )
- {
- RegCloseKey( hKey );
- goto RemoveExit1;
- }
-
- RegFlushKey( hKey );
- RegCloseKey( hKey );
-
- // ==== Remove entry from Service Control Manager ====
- //
- hSCM = OpenSCManager( NULL,
- "ServicesActive",
- SC_MANAGER_ALL_ACCESS );
- if( hSCM == NULL )
- goto RemoveExit4;
-
- i = 0;
- while( TRUE )
- {
- LockSCM = LockServiceDatabase( hSCM );
-
- if( LockSCM != NULL )
- break;
-
- if( i++ >= 5 )
- goto RemoveExit3; // Can't lock database
-
- Sleep( 1000 ); // sleep for a second
- }
-
- // Let's remove the service entry
- //
- hSrvc = OpenService( hSCM,
- PROCSRV, // Service name
- SERVICE_ALL_ACCESS );
- if( hSrvc == NULL )
- goto RemoveExit3;
-
- DeleteService( hSrvc );
-
- CloseServiceHandle( hSrvc );
- UnlockServiceDatabase( LockSCM );
- CloseServiceHandle( hSCM );
-
- return;
-
- RemoveExit1:
- RegCloseKey( hKey );
-
- RemoveExit2:
- printf( "Unable to Update Registry\n" );
- return;
-
- RemoveExit3:
- UnlockServiceDatabase( LockSCM );
- CloseServiceHandle( hSCM );
-
- RemoveExit4:
- printf( "Unable to Update Service Control Manager\n" );
- return;
- }
-
-
- // **************************************************************************
- //
- // FUNCTION: DuplicateEntry
- //
- // PURPOSE: Determines if a duplicate "ProcSrv" exist in
- // the registry.
- //
- // RETURNS:
- // TRUE if name exist, else
- // FALSE if name not found.
- //
- //
- // **************************************************************************
-
- BOOL DuplicateEntry()
- {
- HKEY hKey;
-
- if( RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- PROCSRV_KEY_PATH,
- 0,
- KEY_ENUMERATE_SUB_KEYS,
- &hKey)
- != ERROR_SUCCESS )
- return FALSE;
-
- RegCloseKey( hKey );
- return TRUE;
- }
-
-
- // **************************************************************************
- //
- // FUNCTION: RefreshStoplight()
- //
- // PURPOSE: This routine causes the SQL Service Manager to refresh its
- // list.
- //
- // **************************************************************************
-
- void RefreshStoplight()
- {
- HANDLE hEvent;
-
- hEvent = OpenEvent( EVENT_MODIFY_STATE,
- TRUE,
- "MICROSOFTSQLServiceControlManagerRefresh" );
- if( hEvent )
- {
- SetEvent( hEvent );
- CloseHandle( hEvent );
- }
- }