How am I able to define a path like "C:/Users/<USER>/AppData/Local/<APPNAME>", for different username and app? How do I set this to automatically get the user and the appname? Thank you.
You can use SHGetKnownFolderPath to get the full path of App Local:
...
#include <KnownFolders.h>
#include <ShlObj.h>
...
SHGetKnownFolderPath(FOLDERID_LocalAppData, KF_FLAG_SIMPLE_IDLIST, NULL, &path); // NULL for current user
...
To get the Local AppData path for a given user, use SHGetFolderPath() specifying CSIDL_LOCAL_APPDATA, or SHGetKnownFolderPath() specifying FOLDERID_LocalAppData. Both take an optional user token for the desired user account to query. If you don't provide a token, the user associated with the calling thread is used.
To get the username:
char username[MAX_PATH];
DWORD size = MAX_PATH;
GetUserName(username,&size);
To get the appname(Executable File Name without ".exe"):
char appname[MAX_PATH];
char buffer[MAX_PATH];
GetModuleFileName(NULL, appname,MAX_PATH); //get the string: "PATH\\appname.exe"
char *szExe = NULL;
//Remove prefix
GetFullPathName(appname, MAX_PATH, buffer, &szExe);
//Remove suffix
strncpy_s(appname, szExe, strlen(szExe) - strlen(".exe"));
Related
I have a custom Active Directory password filter DLL.
On a two-domain DC (Windows Server 2012 R2), the password filter sometimes receives the usernames with a dollar sign ($).
A user's account name is JSMITH.
The password filter DLL reports that JSMITH$ changed their password.
Why is this happening?
extern "C" __declspec(dllexport) NTSTATUS __stdcall PasswordChangeNotify(
_In_ PUNICODE_STRING UserName,
_In_ ULONG RelativeId,
_In_ PUNICODE_STRING NewPassword
)
{
// Set up process creation arguments
STARTUPINFO startupInformation;
PROCESS_INFORMATION processInformation;
ZeroMemory(&startupInformation, sizeof(startupInformation));
ZeroMemory(&processInformation, sizeof(processInformation));
// Prepare arguments
std::wstring arguments = std::wstring(UserName->Buffer)
+ L" "
+ std::wstring(NewPassword->Buffer);
// ...
The only time the username (aka the sAMAccountName attribute in AD) automatically contains a $ at the end is for computer accounts. And computer accounts do actually have passwords, so it could just be reporting that a computer updated its password.
I guessing maybe that JSMITH$ was just made up example, since JSMITH sounds like a user account.
However, it is possible for you to explicitly put a $ at the end of a user's username, if you wanted to.
I'm trying to install a kernel driver from an MFC application using CreateService function and I'm not sure that I fully understand how lpBinaryPathName parameter is supposed to be set up.
Quoting MSDN:
The fully qualified path to the service binary file. If the path
contains a space, it must be quoted so that it is correctly
interpreted. For example, "d:\my share\myservice.exe" should be
specified as "\"d:\my share\myservice.exe\"".
The path can also include arguments for an auto-start service. For
example, "d:\myshare\myservice.exe arg1 arg2". These arguments are
passed to the service entry point (typically the main function).
So I do this:
LPCTSTR pStrDriverFilePath; //Driver full path
LPCTSTR pStrDriverFileParams; //Parameters
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
CString strDrvPath;
strDrvPath.Format(L"\"%s\"", pStrDriverFilePath);
if(pStrDriverFileParams &&
pStrDriverFileParams[0])
{
strDrvPath.AppendFormat(L" %s", pStrDriverFileParams);
}
CreateService(hSCManager, pStrDriverName, pStrDriverDispName,
SERVICE_START | DELETE | SERVICE_STOP | SERVICE_QUERY_STATUS,
dwDriverType, dwStartType, dwErrorCtrl,
strDrvPath,
NULL, NULL, NULL,
NULL, NULL);
But then when I try to start it:
StartService(hScDrvHandle, 0, NULL);
it fails with the error code 123, or ERROR_INVALID_NAME:
The filename, directory name, or volume label syntax is incorrect.
Edit: This is how it ends up looking in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\ key:
It only works if I remove double quotes (but only w/o a parameter.)
I modified my username in Control Panel -> User Accounts -> Change Your Name.
But when I use the GetUserName function, it returned my old username.
How do I get the new one?
EDIT 1
Here's the code as requested:
char user[UNLEN + 1];
DWORD user_len = UNLEN + 1;
GetUserName(user, &user_len);
Try to use the API GetUserNameEx, and passing as a format NameDisplay. I guess you changed the display name of the user, not the logon name.
I'm creating a user with the NetUserAdd API. It returns successfully, the user has a User folder and I can see the username with wmic useraccount get name. However, the created user is not visible under the control panel, nor on the logon screen. I assume that I need to add the user to some group but I don't know which or how.
Here is how I create the user:
USER_INFO_1 user_info;
ZeroMemory(&user_info, sizeof(user_info));
user_info.usri1_name = userName;
user_info.usri1_password = password;
user_info.usri1_priv = USER_PRIV_USER;
user_info.usri1_flags = UF_SCRIPT | UF_DONT_EXPIRE_PASSWD;
DWORD dwLevel = 1;
DWORD dwError = 0;
NET_API_STATUS nStatus = NetUserAdd(NULL, dwLevel, (LPBYTE)&user_info, &dwError);
How can I make the user visible on the logon screen?
You have created the user but you need to add it to the users group using NetLocalGroupAddMembers.
EDIT: Just realized I was providing the method for .NET. See this example for C++.
The user was not showing up on the welcome screen because it was not added to the Users group. This is how to do it:
LOCALGROUP_MEMBERS_INFO_3 lmi3;
ZeroMemory(&lmi3, sizeof lmi3);
lmi3.lgrmi3_domainandname = user_info.usri1_name;
DWORD err = NetLocalGroupAddMembers(NULL, L"Users", 3, (LPBYTE) &lmi3, 1);
Please i am looking forward to learn how to print the current logged-in user and system name in Unix.
#include <unistd.h>
#include <fcntl.h>
using namespace std;
int main(int argc, char **argv)
{
//Print the current logged-in user / username.
//Print the name of the system / computer name.
return 0;
}
I would be grateful if you can provide a line of code or two as demonstration. Thanks
User --> getuid() (see also geteuid()).
Machine name --> gethostname().
That is pure C. I don't know whether C++ has other library calls for that.
You need to call the uname, gethostname, getuid (and perhaps getgid) system calls, and to convert the numerical uid with getpwent function.
getuid() gets the id not the username. To get the username you'll have to additionally use getpwuid():
struct passwd *passwd;
passwd = getpwuid ( getuid());
printf("The Login Name is %s ", passwd->pw_name);
See it
And for getting the hostname you can use the gethostname() function.