Below is the code that will
1 - ask for a new account name
2 - ask for a password
3 - create the account (as an administrator)
4 - make the account active
5 - adds the new account to the windows login screen.
Don't forget to do this first:
lmaccess.inc file:
change:
declare import, NetLocalGroupAddMembers(_LPCWSTR servername, _LPCWSTR groupname, _DWORD level, _pointer buf, _DWORD totalentries),int
to:
declare import, NetLocalGroupAddMembers(LPCWSTR servername, LPCWSTR groupname, DWORD level, pointer buf, DWORD totalentries),int
Now here is the program:
$INCLUDE "Registry.inc"
$include "windowssdk.inc"
$include "lm.inc"
$include "Userenv.inc"
DEF USER_NAME,PASSWORD,DESCRIPTION:string
OPENCONSOLE
INPUT "Please enter a username " ,USER_NAME
un2= S2W(USER_NAME)
INPUT "Please enter a password " ,PASSWORD
pw2= S2W(PASSWORD)
INPUT "Please enter a description " ,DESCRIPTION
desc2= S2W(DESCRIPTION)
PRINT
PRINT "Please wait a moment ...."
$define un2
$define pw2
$define desc2
$define USER_FLAGS UF_SCRIPT | UF_DONT_EXPIRE_PASSWD | UF_NORMAL_ACCOUNT
'$define USER_FLAGS UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD | UF_NORMAL_ACCOUNT
create_user()
MakeUserAdmin(un2)
MakeActive()
END
sub create_user()
iwstring wszProfilesDir[MAX_PATH]
DWORD cch
cch = MAX_PATH
GetProfilesDirectoryW(wszProfilesDir, &cch)
lstrcatW(wszProfilesDir, un2)
USER_INFO_1 ui
ui.usri1_name = un2
ui.usri1_password = pw2
ui.usri1_password_age = 0
ui.usri1_priv = USER_PRIV_USER ' guest/user/admin
ui.usri1_home_dir = wszProfilesDir ' can be null
ui.usri1_comment = desc2 ' can be null
ui.usri1_flags = USER_FLAGS
ui.usri1_script_path = 0
cch = LEN(ui)
NET_API_STATUS status
status = NetUserAdd(NULL, 1, &ui, &cch)
select (status)
case ERROR_ACCESS_DENIED:
MessageBoxW(0, L"NetUserAdd: The user does not have access to the requested information")
case NERR_InvalidComputer:
MessageBoxW(0, L"NetUserAdd: The computer name is invalid")
case NERR_NotPrimary:
MessageBoxW(0, L"NetUserAdd: The operation is allowed only on the primary domain controller of the domain")
case NERR_GroupExists:
MessageBoxW(0, L"NetUserAdd: The group already exists")
case NERR_PasswordTooShort:
MessageBoxW(0, L"NetUserAdd: The password is shorter than required")
case NERR_UserExists:
' success
MessageBoxW(0, L"This user name has already been used.")
case NERR_Success:
MessageBoxW(0, L"The new user account was created successfully.")
' success, optionally run ie4uinit.exe to initialize sounds
STARTUPINFOW si
PROCESS_INFORMATION pi
ZeroMemory(&si, len(si))
si.cb = len(si)
GetSystemDirectory(wszProfilesDir, MAX_PATH)
if (CreateProcessWithLogonW(un2, L".", pw2, LOGON_WITH_PROFILE, NULL, L"ie4uinit.exe", 0,0, wszProfilesDir, &si, &pi))
CloseHandle(pi.hProcess)
CloseHandle(pi.hThread)
endif
endselect
endsub
sub MakeUserAdmin(wstring pszUserName),BOOL
' SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY
PSID pSidAdmins
pSidAdmins = NULL
BOOL bOk
for bOk=0 to 0
' initialize well-known SID of the local administrators group
if (0=AllocateAndInitializeSid(&SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, _
0, 0, 0, 0, 0, 0, &pSidAdmins))
breakfor
endif
iwstring szGroupName[UNLEN + 1]
iwstring szDomainName[DNLEN + 1]
ULONG cchGroupName
cchGroupName = UNLEN + 1
ULONG cchDomainName
cchDomainName = DNLEN + 1
SID_NAME_USE Use
' convert SID to the localized name of the group
if (0=LookupAccountSidW(NULL, pSidAdmins, szGroupName, &cchGroupName, szDomainName, &cchDomainName, &Use))
breakfor
endif
' prepare user name
LOCALGROUP_MEMBERS_INFO_3 info
info.lgrmi3_domainandname = pszUserName
' add the user to the administrators group
if (NetLocalGroupAddMembers(NULL, szGroupName, 3, &info, 1))
breakfor
endif
next bOk
if (pSidAdmins) then FreeSid(pSidAdmins)
return bOk
endsub
SUB MakeActive()
SYSTEM "cmd.exe" , "/c net user Safeuser /active:yes"
sleep(1000)
result = RegSetDWValue("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList", 1, "Safeuser")
RETURN
ENDSUB
Tested on XP pro and Win 7
Special thanks to sapero who did most of this work.
Regards,
Andy.
Andy,
I'm getting:
Compiling...
create new user.eba
Unable to Open - registry.inc
File: C:\Program Files\EBDev\projects\create new user.eba (159) Warning: undeclared function 'RegSetDWValue'
Error(s) in compiling "C:\Program Files\EBDev\projects\create new user.eba"
Where does "RegSetDWValue" come from, because I can't find that string in any of my files
Brian
Hi Brian,
Save this file and call it "Registry.inc"
TYPE FileTime
INT dwLowDateTime
INT dwHighDateTime
ENDTYPE
DECLARE IMPORT,RegOpenKeyExA(hkey as Uint,subkey as string,options as int,security as int,result as pointer),INT
DECLARE IMPORT,RegQueryValueExA(hkey as Uint,valuename as string,reserved as pointer,typ as pointer,keyvalue as pointer,size as pointer),INT
DECLARE IMPORT,RegCloseKey(hkey as Uint),INT
DECLARE IMPORT,RegCreateKeyExA(hKey AS INT,lpSubKey AS STRING,Reserved AS INT,lpClass AS STRING,dwOptions AS INT,samDesired AS INT,lpSecurityAttributes AS int,phkResult AS INT BYREF,lpdwDisposition AS INT BYREF),INT
DECLARE IMPORT,RegDeleteKeyA(hKey AS Uint,SubKey AS STRING),INT
DECLARE IMPORT,RegSetValueExA(hKey AS INT,lpValueName AS STRING,Reserved AS INT,dwType AS INT,lpData AS POINTER,cbData AS INT),INT
DECLARE IMPORT,RegDeleteValueA(hKey:INT, lpValueName:STRING),INT
DECLARE IMPORT,RegEnumKeyExA(hKey AS INT,dwIndex AS INT,lpName AS STRING,lpcbName AS POINTER,lpReserved AS INT,lpClass AS STRING,lpcbClass AS POINTER,lpftLastWriteTime AS FILETIME),INT
DECLARE IMPORT,RegEnumValueA(hKey AS INT,dwIndex AS INT,lpValueName AS STRING,lpcbValueName AS POINTER,lpReserved AS INT,lpType AS POINTER,lpData AS POINTER BYREF,lpcbData AS POINTER),INT
DECLARE IMPORT,RegQueryInfoKeyA(INT hKey,POINTER lpClass,POINTER lpcchClass,POINTER lpReserved,POINTER lpcSubKeys,POINTER lpcbMaxSubKeyLen,POINTER lpcbMaxClassLen,POINTER lpcValues,POINTER lpcbMaxValueNameLen,POINTER lpcbMaxValueLen,POINTER lpcbSecurityDescriptor,FILETIME lpftLastWriteTime),INT
SETID "HKEY_CLASSES_ROOT", 0x80000000
SETID "HKEY_CURRENT_USER", 0x80000001
SETID "HKEY_LOCAL_MACHINE", 0x80000002
SETID "HKEY_USERS", 0x80000003
SETID "HKEY_PERFORMANCE_DATA",0x80000004
SETID "HKEY_CURRENT_CONFIG", 0x80000005
SETID "HKEY_DYN_DATA", 0x80000006
SETID "KEY_ALL_ACCESS", 63
SETID "REG_SZ",1
SETID "REG_EXPAND_SZ",2
SETID "REG_BINARY", 3
SETID "REG_DWORD", 4
'SETID "REG_QWORD", 11
Sub GetRoot(Key as string),UInt
string rf
UInt retval
retval=0
rf=left$(Key,instr(Key,"\\")-1)
select rf
case "HKEY_CLASSES_ROOT"
retval= @HKEY_CLASSES_ROOT
case "HKEY_CURRENT_USER"
retval=@HKEY_CURRENT_USER
case "HKEY_LOCAL_MACHINE"
retval=@HKEY_LOCAL_MACHINE
case "HKEY_USERS"
retval=@HKEY_USERS
case "HKEY_PERFORMANCE_DATA"
retval=@HKEY_PERFORMANCE_DATA
case "HKEY_CURRENT_CONFIG"
retval=@HKEY_CURRENT_CONFIG
case "HKEY_DYN_DATA"
retval=@HKEY_DYN_DATA
endselect
return retval
EndSub
Sub RegGetValue(Key as string,opt ValueName as string),string
string retval,rf,ky
UInt root,ret,ln,typ
int getdw
retval=""
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
RegQueryValueExA(Ret,ValueName,NULL,typ,retval,ln)
'if typ=2:'Expand_SZ
' ln=255
' RegQueryValueExA(Ret,ValueName,NULL,typ,getdw,ln)
' retval=str$(getdw)
'endif
if typ=4:'Dword
ln=4
RegQueryValueExA(Ret,ValueName,NULL,typ,getdw,ln)
retval=str$(getdw)
endif
if typ=11:'Qword
ln=8
RegQueryValueExA(Ret,ValueName,NULL,typ,getdw,ln)
retval=str$(getdw)
endif
'PRINT typ
endif
RegCloseKey(ret)
return retval
EndSub
Sub RegGetEntryType(Key as string,opt ValueName as string),INT
string retval,rf,ky
UInt root,ret,ln,typ
int getdw
retval=""
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
RegQueryValueExA(Ret,ValueName,NULL,typ,retval,ln)
endif
RegCloseKey(ret)
return typ
EndSub
Sub RegDeleteValue(Key as string,opt ValueName as string),string
string retval,rf,ky
UInt root,ret,ln,typ
int getdw
retval=""
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
IF RegDeleteValueA(ret,valuename) = 0
retval = "0"
ELSE
retval = "1"
ENDIF
endif
RegCloseKey(ret)
return retval
EndSub
Sub RegSetValue(Key as string,Value as string,opt ValueName as string),int
string rf,ky
UInt root,ret,ln,typ
int retval,tmp
retval=0
tmp=0
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
RegCreateKeyExA(GetRoot(Key),ky,0,"",0,@KEY_ALL_ACCESS,0,ret,tmp)
tmp=0
ln=len(value)+1
retval=RegSetValueExA(ret,ValueName,tmp,@REG_SZ,Value,ln)
RegCloseKey(ret)
return retval
EndSub
Sub RegSetDWValue(Key as string,Value as int,opt ValueName as string),int
string rf,ky
UInt root,ret,ln,typ
int retval,tmp
retval=0
tmp=0
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
RegCreateKeyExA(GetRoot(Key),ky,0,"",0,@KEY_ALL_ACCESS,0,ret,tmp)
tmp=0
ln=4
retval=RegSetValueExA(ret,ValueName,tmp,@REG_DWORD,Value,ln)
RegCloseKey(ret)
return retval
EndSub
Sub RegSetBWValue(Key as string,lns as Uint,Value as int,opt ValueName as string),int
string rf,ky
UInt root,ret,typ
int retval,tmp
retval=0
tmp=0
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
RegCreateKeyExA(GetRoot(Key),ky,0,"",0,@KEY_ALL_ACCESS,0,ret,tmp)
tmp=0
'ln=8
retval=RegSetValueExA(ret,ValueName,tmp,@REG_BINARY,Value,lns)
RegCloseKey(ret)
PRINT "**",HEX$(Value)
return retval
EndSub
Sub RegCreateKey(Key as string),int
string rf,ky
UInt root,ret
int retval,tmp,ln
tmp=0
ln=255
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
retval=RegCreateKeyExA(GetRoot(Key),ky,0,"",0,@KEY_ALL_ACCESS,0,ret,tmp)
RegCloseKey(ret)
return retval
EndSub
Sub RegDeleteKey(Key as string),int
string rf,ky
int retval
rf=left$(Key,instr(Key,"\\")-1)
ky=right$(Key,len(Key)-1-len(rf))
retval=RegDeleteKeyA(GetRoot(Key),ky)
return retval
EndSub
Sub RegEnumKey(STRING Key,INT Index),STRING
FileTime ft
UInt root,ret,ln
INT x,cc
string rf,ky
string retval,ln$
ln=255
rf=left$(Key,INSTR(Key,"\\")-1)
ky=right$(Key,(len(Key)-1)-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
RegEnumKeyExA(ret,index,retval,ln,NULL,"",ln,ft)
ENDIF
RegCloseKey(ret)
return retval
EndSub
Sub RegEnumEntryName(STRING Key,INT Index),string
FileTime ft
int getdw
UINT ret,typ
STRING retval
string rf,ky
INT ln
lpClass=""
ln=255
rf=left$(Key,INSTR(Key,"\\")-1)
ky=right$(Key,(len(Key)-1)-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
RegEnumValueA(ret,Index,retval,ln,NULL,typ,NULL,NULL)
ENDIF
RegCloseKey(ret)
return retval
EndSub
Sub RegCountSubKeys(STRING Key),INT
FileTime ft
INT ln,retval
ln=255
UINT ret
lpClass=""
rf=left$(Key,INSTR(Key,"\\")-1)
ky=right$(Key,(len(Key)-1)-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
RegQueryInfoKeyA(ret,lpClass,ln,NULL,retval,NULL,NULL,NULL,NULL,NULL,NULL,ft)
RegCloseKey(ret)
ENDIF
'Returns the number of sub-keys under this key, or 0 for error
return retval
EndSub
Sub RegCountEntries(STRING Key),INT
FileTime ft
UINT ret
INT ln
INT retval
STRING lpClass
string rf,ky
lpClass = ""
ln=255
rf=left$(Key,INSTR(Key,"\\")-1)
ky=right$(Key,(len(Key)-1)-len(rf))
if RegOpenKeyExA(GetRoot(Key),ky,0,@KEY_ALL_ACCESS,ret) = 0
RegQueryInfoKeyA(ret,lpClass,ln,NULL,NULL,NULL,NULL,retval,NULL,NULL,NULL,ft)
RegCloseKey(ret)
ENDIF
'Returns the number of values under this key
return retval
EndSub
It has the RegSetDWValue in it.
Add this to your first line of the program.
Please post back if you were successfull or not, if not I will help you compile it, no problem.
Best wishes,
Andy.
Andy,
Created registry.inc, and re-compiled. Now I get:
Compiling...
create new user.eba
File: registry.inc (84) Warning: Unreferenced local variable: root
File: registry.inc (99) Warning: Unreferenced local variable: root
File: registry.inc (99) Warning: Unreferenced local variable: getdw
File: registry.inc (118) Warning: Unreferenced local variable: typ
File: registry.inc (118) Warning: Unreferenced local variable: root
File: registry.inc (118) Warning: Unreferenced local variable: getdw
File: registry.inc (135) Warning: Unreferenced local variable: typ
File: registry.inc (135) Warning: Unreferenced local variable: root
File: registry.inc (152) Warning: Unreferenced local variable: typ
File: registry.inc (152) Warning: Unreferenced local variable: root
File: registry.inc (170) Warning: Unreferenced local variable: typ
File: registry.inc (170) Warning: Unreferenced local variable: root
File: registry.inc (183) Warning: Unreferenced local variable: root
File: registry.inc (204) Warning: Uninitialized variable: retval - )
File: registry.inc (208) Warning: Unreferenced local variable: root
File: registry.inc (208) Warning: Unreferenced local variable: cc
File: registry.inc (208) Warning: Unreferenced local variable: x
File: registry.inc (208) Warning: Unreferenced local variable: ln$
File: registry.inc (222) Warning: Uninitialized variable: retval - )
File: registry.inc (226) Warning: Unreferenced local variable: ft
File: registry.inc (226) Warning: Unreferenced local variable: getdw
File: winreg.inc (140) duplicate declaration - LONG
File: winreg.inc (191) duplicate declaration - LONG
File: winreg.inc (195) duplicate declaration - LONG
File: winreg.inc (209) duplicate declaration - LONG
File: winreg.inc (219) duplicate declaration - LONG
File: winreg.inc (247) duplicate declaration - LONG
File: winreg.inc (257) duplicate declaration - LONG
File: winreg.inc (271) duplicate declaration - LONG
File: winreg.inc (275) duplicate declaration - LONG
File: winreg.inc (288) duplicate declaration - LONG
File: winreg.inc (336) duplicate declaration - LONG
File: winreg.inc (349) duplicate declaration - LONG
File: winreg.inc (391) duplicate declaration - LONG
File: winreg.inc (459) duplicate declaration - LONG
File: winreg.inc (463) duplicate declaration - LONG
File: winreg.inc (501) duplicate declaration - LONG
Error(s) in compiling "C:\Program Files\EBDev\projects\create new user.eba"
And yes, I have Sapero's windowssdk
Brian
Hi Brian,
my mistake, I forgot that I had edited the Windowssdk.inc file.
Open it and edit the line
$include "winreg.inc" to ' $include "winreg.inc" (commented out) or just delete it.
As for the warnings - they appear because some variable have not been set an initial value
Just forget about them.
Once you have edited the Windowssdk.inc file it should compile.
Let me know how you get on,
Thanks,
Andy.
Or better add the following before $include windowssdk.inc
$define __winreg_inc__
After you define this condition, winreg.inc will be "excluded" from compilation, because it has an $ifndef at the beginning.
Yep, that worked OK with Sapero's mod. Ran the program and added
a new user, etc, but nothing happened, ie, no user was added, even
though it said was successful
Oh well, just happy to get it to compile!
Brian
Did you try compiling it THEN running the exe as an Administrator ?
What os are you using Brian ?
XP, vista 7 ?
Andy.
Andy,
XP SP3. I've just run it again with Run as... and Administrator. Funny thing
is, I used the same username as last time, and it said it was already in use!
So I've just looked in Manage>Local Users and Groups/Users, and there it
was, but the user name doesn't show up to be selected when you boot the PC
I also noticed in the user Properties>Profile, Home Folder>Local Path, there was
a missing backslash in the Documents and Settings path
Brian
Hi Brian,
sorry I coudn't get back to you yesterday was very busy testing the program on several machines.
What you need to do is add a couple of lines.
DEF str:string
then change this section:
INPUT "Please enter a username " ,USER_NAME
un2= S2W(USER_NAME)
INPUT "Please enter a password " ,PASSWORD
pw2= S2W(PASSWORD)
INPUT "Please enter a description " ,DESCRIPTION
desc2= S2W(DESCRIPTION)
to
INPUT "Please enter a username " ,USER_NAME
un2= S2W(USER_NAME)
INPUT "Please enter a password " ,PASSWORD
pw2= S2W(PASSWORD)
INPUT "Please enter a description " ,DESCRIPTION
desc2= S2W(DESCRIPTION)
str = "\\" + USER_NAME
prof = S2W(str)
and finally modify the line:
lstrcatW(wszProfilesDir, un2) to lstrcatW(wszProfilesDir, prof)
This should add in the missing backslash.
I have tested this on:
Windows XP Home SP2 & SP3
XP Pro SP2 & SP3
Vista Home Basic SP2
Win 7 Ultimate 32
It works on all these platforms.
Thought the origional code was complete so sorry it wasn't quite there but I think this should be the finished artical now.
Andy.
:)
Andy,
Yep, that worked OK. Might mess about making a GUI out of it,
and making it pretty!
Brian
Great news Brian,
Regards,
Andy.