
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>

#define KEYNAME "WizzKey Red Label"
#define DRVNAME "wkrl.sys"
#define DRV_NAME "wkrl"

char tbuf[100];

BOOL RunningAsAdministrator()
{
   BOOL  fAdmin;
   HANDLE htkThread;
   TOKEN_GROUPS *ptg = NULL;
   DWORD cbTokenGroups;
   DWORD iGroup;
   SID_IDENTIFIER_AUTHORITY SystemSidAuthority= SECURITY_NT_AUTHORITY;
   PSID psidAdmin;

   // This function returns TRUE if the user identifier associated with this
   // process is a member of the the Administrators group.

   // First we must open a handle to the access token for this thread.

   if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &htkThread))
      if (GetLastError() == ERROR_NO_TOKEN)
      {
         // If the thread does not have an access token, we'll examine the
         // access token associated with the process.

         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htkThread))
         return FALSE;
      }
      else return FALSE;

   // Then we must query the size of the group information associated with
   // the token. Note that we expect a FALSE result from GetTokenInformation
   // because we've given it a NULL buffer. On exit cbTokenGroups will tell
   // the size of the group information.

   if (GetTokenInformation(htkThread, TokenGroups, NULL, 0, &cbTokenGroups))
      return FALSE;

   // Here we verify that GetTokenInformation failed for lack of a large
   // enough buffer.

   if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
      return FALSE;

   // Now we allocate a buffer for the group information.
   // Since _alloca allocates on the stack, we don't have
   // to explicitly deallocate it. That happens automatically
   // when we exit this function.

   if (!(ptg= _alloca(cbTokenGroups))) return FALSE;

   // Now we ask for the group information again.
   // This may fail if an administrator has added this account
   // to an additional group between our first call to
   // GetTokenInformation and this one.

   if (!GetTokenInformation(htkThread, TokenGroups, ptg, cbTokenGroups,
                                       &cbTokenGroups
                           )
      )
      return FALSE;

   // Now we must create a System Identifier for the Admin group.

   if (!AllocateAndInitializeSid
          (&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
                                   DOMAIN_ALIAS_RID_ADMINS,
                                   0, 0, 0, 0, 0, 0,
                                   &psidAdmin
          )
      )
      return FALSE;

   // Finally we'll iterate through the list of groups for this access
   // token looking for a match against the SID we created above.

   fAdmin= FALSE;

   for (iGroup= 0; iGroup < ptg->GroupCount; iGroup++)
      if (EqualSid(ptg->Groups[iGroup].Sid, psidAdmin))
      {
         fAdmin= TRUE;

         break;
      }

   // Before we exit we must explicity deallocate the SID
   // we created.

   FreeSid(psidAdmin);

   return(fAdmin);
}





/********************************************************************\
*  Function: int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)  *
*                                                                    *
*   Purpose: Initializes Application                                 *
*                                                                    *
*  Comments: Standard template                                       *
*                                                                    *
*                                                                    *
\********************************************************************/


int PASCAL WinMain( HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszCmdLine,
                    int nCmdShow )

{

	DWORD dwVal;
	BOOL SysCopied=TRUE;
	long lResult;
	HKEY hkDefaults;
	char *WinRoot;

	// check if running on Windows NT, if not, display notice and terminate
	if( GetVersion() & 0x80000000 )
	{	MessageBoxA( NULL,
         "This application can only be run on Windows NT.\n"
         "This application will now terminate.",
         KEYNAME,
         MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
		return( 1 );
	}

	if( !RunningAsAdministrator)
	{	MessageBoxA( NULL,
         "You must be an administrator to register the "KEYNAME" device driver.\n"
         "This application will now terminate.",
         KEYNAME,
         MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
		return( 1 );
	}

	if (MessageBoxA( NULL,
         "Installation of the "KEYNAME" device driver for Windows NT.\n\n"
         "This application will copy the driver '"DRVNAME"' to the\n"
		 "system directory '%Systemroot%\\System32\\drivers' and\n"
		 "add the "KEYNAME" configuration to the Registry.", 
         KEYNAME,
         MB_OKCANCEL | MB_SETFOREGROUND )
		== IDCANCEL) return(1);

	WinRoot=getenv("SystemRoot");
	if(WinRoot==NULL)
	{	MessageBoxA( NULL,
		 "Could not find the systemroot!\n\n"
		 "You need to copy the "KEYNAME" driver '"DRVNAME"'\n"
		 "manually to: %Systemroot%\\System32\\drivers.\n"
		 "This application will however continue\n"
		 "to add the "KEYNAME" configuration to the Registry.",
		 KEYNAME,
		 MB_OK | MB_SETFOREGROUND | MB_ICONEXCLAMATION );
		SysCopied=FALSE;
	}
	else
	{
		strcat(WinRoot,"\\System32\\drivers\\"DRVNAME);
		if(access(".\\"DRVNAME,'r')==-1)
		{	// file not found
			MessageBoxA( NULL,
			 "Could not find the "KEYNAME" driver!\n\n"
			 "You need to copy the "KEYNAME" driver '"DRVNAME"'\n"
			 "manually to: %Systemroot%\\System32\\drivers.\n"
			 "This application will however continue to\n"
			 "add the "KEYNAME" configuration to the Registry.",
			 KEYNAME,
			 MB_OK | MB_SETFOREGROUND | MB_ICONEXCLAMATION );
			SysCopied=FALSE;
		}
		else
		{	if( !CopyFile(".\\"DRVNAME, WinRoot,FALSE) )
			{	MessageBoxA( NULL,
				 "Could not copy "KEYNAME" driver!\n\n"
				 "You need to copy the "KEYNAME" driver '"DRVNAME"'\n"
				 "manually to: %Systemroot%\\System32\\drivers.\n"
				 "This application will however continue to\n"
				 "add the "KEYNAME" configuration to the Registry.",
				 KEYNAME,
				 MB_OK | MB_SETFOREGROUND | MB_ICONEXCLAMATION );
				SysCopied=FALSE;
			}
		}
	}

	lResult=RegCreateKeyEx(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\Services\\"DRV_NAME,0,"\\0",
							REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkDefaults, &dwVal);

	if(lResult!=ERROR_SUCCESS)
	{	MessageBoxA( NULL,
		 "Could not open or create key in Registry: the " KEYNAME "\n"
		 "driver is not configured properly.\n"
		 "This application will now terminate.",
		 KEYNAME,
		 MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
		return( 1 );
	}

	dwVal=0x1;
	lResult=RegSetValueEx(hkDefaults,"ErrorControl",0,REG_DWORD, (LPBYTE) &dwVal, sizeof(dwVal));
	if(lResult!=ERROR_SUCCESS)
	{	MessageBoxA( NULL,
		 "Could not set value in Registry: the " KEYNAME " driver\n"
		 "is not configured properly.\n"
 		 "This application will now terminate.",
		 KEYNAME,
		 MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
		return( 1 );
	}

	dwVal=0x2;
	lResult=RegSetValueEx(hkDefaults,"Start",0,REG_DWORD, (LPBYTE) &dwVal, sizeof(dwVal));
	if(lResult!=ERROR_SUCCESS)
	{	MessageBoxA( NULL,
		 "Could not set value in Registry: the " KEYNAME " driver\n"
		 "is not configured properly.\n"
 		 "This application will now terminate.",
		 KEYNAME,
		 MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
		return( 1 );
	}

	dwVal=0x1;
	lResult=RegSetValueEx(hkDefaults,"Type",0,REG_DWORD, (LPBYTE) &dwVal, sizeof(dwVal));
	if(lResult!=ERROR_SUCCESS)
	{	MessageBoxA( NULL,
		 "Could not set value in Registry: the " KEYNAME " driver\n"
		 "is not configured properly.\n"
 		 "This application will now terminate.",
		 KEYNAME,
		 MB_OK | MB_ICONSTOP | MB_SETFOREGROUND );
		return( 1 );
	}

	RegCloseKey(hkDefaults);
	if (SysCopied)
	{	MessageBox(NULL, KEYNAME " driver installed and configured", KEYNAME, MB_OK);
	}
	else
	{	MessageBoxA( NULL,
		 KEYNAME " driver configured, but not yet installed!\n\n"
		 "Do not forget to copy the driver.\n"
 		 "This application will now terminate.",
		 KEYNAME,
		 MB_OK | MB_SETFOREGROUND | MB_ICONEXCLAMATION );
	}
}
