Click here to Skip to main content
15,896,912 members
Articles / Programming Languages / C++

A general purpose NT Service Class

Rate me:
Please Sign up or sign in to vote.
4.59/5 (20 votes)
6 Jul 2004CPOL2 min read 61.6K   3.1K   43  
Build a NT Service
/******************************************************************************/
/*
/*    copyright 2003  , Stefan Voitel - Berlin / Germany
/*
/*    stefan.voitel@winways.de	
/******************************************************************************/

#include <windows.h>
#include <lm.h>
#include <AccountDialog.rh>

class cSvcConfigDialog {

 public:
  DWORD LastError;

   cSvcConfigDialog  (const char *SvcName) {
       ZeroMemory (m_ServiceName,sizeof(m_ServiceName));
       strncpy (m_ServiceName,SvcName,sizeof(m_ServiceName) -1);

       DialogBoxParam (GetModuleHandle(NULL),MAKEINTRESOURCE(SvcAccountDialog),
                                                   NULL,DlgProc,(LPARAM) this);
      }

 private:
   char m_ServiceName[255];

   bool cSvcConfigDialog::InitAccountDialog (HWND);
   bool cSvcConfigDialog::ConfigureAccount  (HWND);

   static BOOL CALLBACK cSvcConfigDialog::DlgProc (HWND,UINT,WPARAM,LPARAM);
};


#define SYSACCOUNT  	  	"LocalSystem"

bool cSvcConfigDialog::InitAccountDialog (HWND hDlg) {
SC_HANDLE 	hsc,hsrv;

SetWindowText (GetDlgItem(hDlg,IDC_PWD2),"<none>");

if ( (hsc = OpenSCManager (NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE)) != NULL) {
   if ((hsrv = OpenService(hsc,m_ServiceName,SERVICE_QUERY_CONFIG)) != NULL) {
      DWORD					  	size;
      QUERY_SERVICE_CONFIG	*psc;

      QueryServiceConfig (hsrv,NULL,0,&size);

      if (size && (psc = (QUERY_SERVICE_CONFIG*) HeapAlloc(GetProcessHeap(),
     														HEAP_ZERO_MEMORY,size)) != NULL) {
         if (QueryServiceConfig (hsrv,psc,size,&size)) {
				DWORD 				 n;
				NET_DISPLAY_USER  *acc;

            SetWindowText (hDlg,psc->lpDisplayName);

            SendMessage (GetDlgItem(hDlg,IDC_AUTOSTART),BM_SETCHECK,
            					  (WPARAM) psc->dwStartType == SERVICE_AUTO_START,0);

            SendMessage (GetDlgItem(hDlg,IDC_INTERACTIVE),BM_SETCHECK,
     					 (WPARAM) psc->dwServiceType & SERVICE_INTERACTIVE_PROCESS,0);

            SetWindowText(GetDlgItem(hDlg,IDC_ACCOUNT),psc->lpServiceStartName);

            if (stricmp (psc->lpServiceStartName,SYSACCOUNT))
               EnableWindow (GetDlgItem(hDlg,IDC_INTERACTIVE),false);

            NetQueryDisplayInformation (NULL,1,0,0xFFFF,0xFFFFFF,&n,
            																	 (void **) &acc);
            while (n--) {
               char acs [128];
               char usr [64];

               WideCharToMultiByte(CP_ACP,0,acc[n].usri1_name,-1,usr,
               														sizeof(usr),NULL,NULL);
               wsprintf (acs,".\\%s",usr);
               SendMessage (GetDlgItem(hDlg,IDC_ACCOUNT),CB_ADDSTRING,0,
               																	(LPARAM) acs);
               }
            NetApiBufferFree ((void*) acc);
            SendMessage (GetDlgItem(hDlg,IDC_ACCOUNT),CB_ADDSTRING,0,
            															  (LPARAM) SYSACCOUNT);
            LastError = ERROR_SUCCESS;
				}
         else LastError = GetLastError();				
			HeapFree (GetProcessHeap(),0,psc);
			}
      else LastError = GetLastError();
      CloseServiceHandle (hsrv);
      }
   else LastError = GetLastError();
   CloseServiceHandle (hsc);
	}
else LastError = GetLastError();

return LastError == ERROR_SUCCESS;
}

// --------------------------------

bool cSvcConfigDialog::ConfigureAccount (HWND hDlg) {
SC_HANDLE 	hsc,hsrv;

BOOL 	sysacc;
char	account[48];
char	pwd1[24],pwd2[24];

GetWindowText (GetDlgItem(hDlg,IDC_ACCOUNT),account,sizeof(account));
sysacc =  !stricmp (account,SYSACCOUNT);

if (! sysacc) {
   GetWindowText (GetDlgItem(hDlg,IDC_PWD1),pwd1,sizeof(pwd1));
   GetWindowText (GetDlgItem(hDlg,IDC_PWD2),pwd2,sizeof(pwd2));

   if (strcmp (pwd1,pwd2))	{
   SetWindowText (GetDlgItem(hDlg,IDC_PWD2),"<none>");
   SendMessage (GetDlgItem(hDlg,IDC_PWD2),EM_SETSEL,0,-1);
	SetFocus (GetDlgItem(hDlg,IDC_PWD2));
   LastError = ERROR_WRONG_PASSWORD;	
   return false;
   }
}

if ((hsc = OpenSCManager (NULL,NULL,SC_MANAGER_ALL_ACCESS)) != NULL)	{
	if ((hsrv = OpenService (hsc,m_ServiceName,SERVICE_ALL_ACCESS)) != NULL) {
      BOOL start = (BOOL) SendMessage(GetDlgItem(hDlg,IDC_AUTOSTART),
                                                            BM_GETCHECK,0,0);
      BOOL iactv = (BOOL) SendMessage(GetDlgItem(hDlg,IDC_INTERACTIVE),
                                                            BM_GETCHECK,0,0);

      UINT stype = SERVICE_WIN32_OWN_PROCESS;
      if (sysacc && iactv)
		   stype |= SERVICE_INTERACTIVE_PROCESS;

		if (ChangeServiceConfig (hsrv,stype,
  		 		  	start ? SERVICE_AUTO_START : SERVICE_DEMAND_START,
	 		   		  SERVICE_ERROR_NORMAL,NULL,NULL,NULL,NULL,
				  		  		 sysacc ? SYSACCOUNT : account,sysacc ? "" : pwd1,NULL))

         LastError = ERROR_SUCCESS;
      else LastError = GetLastError();
		CloseServiceHandle (hsrv);
		}
   else LastError = GetLastError();
	CloseServiceHandle (hsc);
   }
else LastError = GetLastError();

return LastError == ERROR_SUCCESS;
}

// --------------------------------

BOOL CALLBACK cSvcConfigDialog::DlgProc (HWND hDlg,UINT uMsg,WPARAM wParam,
                                                               LPARAM lParam) {
switch (uMsg) {

   case WM_INITDIALOG: {
      cSvcConfigDialog *O = (cSvcConfigDialog*) lParam;
   	SetWindowLong (hDlg,GWL_USERDATA,(LONG) (LPARAM) O);

		if (! O->InitAccountDialog (hDlg)) {
         char  *LastError;

         FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM|
                               FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL,O->LastError,
         					               MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
                                                     (char*) &LastError,0,NULL);
         MessageBox (NULL,LastError,O->m_ServiceName,MB_ICONSTOP);
         LocalFree (LastError);
      	EndDialog (hDlg,O->LastError);
         }
//      else {
//         SetWindowPos (hDlg,HWND_TOPMOST,200,200,0,0,SWP_NOSIZE);
//         }
         
   	break;
      }

	case WM_COMMAND: {

      cSvcConfigDialog *O = (cSvcConfigDialog*) (LPARAM)
                                              GetWindowLong(hDlg,GWL_USERDATA);
      switch (LOWORD(wParam))	{

         case IDOK:

				if (O->ConfigureAccount(hDlg)) {
            	EndDialog (hDlg,ERROR_SUCCESS);
               }

            else {
               char  *LastError;
               RECT  rc,rcs,rcw;

               GetWindowRect(hDlg,&rc);
               GetWindowRect(GetDlgItem(hDlg,IDC_STATUS),&rcs);

               SystemParametersInfo (SPI_GETWORKAREA,0,&rcw,0);

               int top    = rc.top;
               int height = (rcs.bottom +8) -rc.top;

               if ((rc.bottom +height) > rcw.bottom) {
                  top = rcw.bottom - height;
                  }

               SetWindowPos (hDlg,HWND_TOPMOST,rc.left,top,rc.right-rc.left,
                                                                      height,0);
               FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM|
                               FORMAT_MESSAGE_ALLOCATE_BUFFER,NULL,O->LastError,
         					               MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
                                                     (char*) &LastError,0,NULL);

               SetWindowText (GetDlgItem (hDlg,IDC_STATUS),LastError);
               LocalFree (LastError);
               Beep (600,333);
               }
         	break;

			case IDCANCEL:
            O->LastError = ERROR_CANCELLED;
         	EndDialog (hDlg,ERROR_CANCELLED);
				break;

         case IDC_ACCOUNT:
            if (HIWORD (wParam) == CBN_EDITUPDATE ||
                           HIWORD (wParam) == CBN_KILLFOCUS) {
               char	acc[48];
               GetWindowText(GetDlgItem(hDlg,IDC_ACCOUNT),acc,sizeof(acc));
               EnableWindow (GetDlgItem(hDlg,IDC_INTERACTIVE),
                                                !stricmp (acc,SYSACCOUNT));
               }
            break;
         }
   	break;
      }
   }
return 0;
}
// -----------------------------------------------------------------------------
// EOF

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions