/******************************************************************************/
/*
/*    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
