Re: Windows API: GetUserName: Retrieve the name of the user associated with the current thread.

2023-08-20 Thread BoQsc via Digitalmars-d-learn

 Update: GetUserName by print to stdout

Main function has been updated with `string[] args` and a new 
feature:

```
if (args.length > 1 && args[1] == "print") {
write(username);
}
```


 Usage:
`WindowsGetUserName.exe print`

 Demonstration


![img1](https://i.imgur.com/dWPlo8L.png)

 WindowsGetUserName.d
```d
import core.sys.windows.windows;
import std.conv;
import std.stdio;
import std.range;

pragma(lib, "advapi32.lib");

/**
 * Retrieves the currently logged-in user's name in a safe manner.
 *
 * This function first determines the required buffer size, 
allocates memory for the username,

 * and then retrieves the username.
 *
 * Returns:
 *   - The username as a string if successful.
 *   - An empty string if an error occurs.
 */
string getSafeUsername() @system {
wchar[] userName;
DWORD userNameSize = 0;

// First, try GetUserNameW (Unicode version)
if (!GetUserNameW(null, )) {
int error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER) {
// Failed for a reason other than an insufficient 
buffer

return "";
}
}

// Allocate memory for userName
scope(exit) userName.length = 0; // Ensure memory is released 
if an exception occurs

userName.length = userNameSize;

// Retrieve the user name by calling GetUserNameW
if (GetUserNameW(userName.ptr, )) {
// Successfully retrieved the user name, convert it to a 
string

return to!string(userName);
}

// If GetUserNameW fails, try GetUserNameA (ANSI version)
char[] userNameA;
userNameSize = 0;

if (!GetUserNameA(null, )) {
int errorA = GetLastError();
if (errorA != ERROR_INSUFFICIENT_BUFFER) {
// Failed for a reason other than an insufficient 
buffer

return "";
}
}

// Allocate memory for userNameA
scope(exit) userNameA.length = 0; // Ensure memory is 
released if an exception occurs

userNameA.length = userNameSize;

// Retrieve the user name by calling GetUserNameA
if (GetUserNameA(userNameA.ptr, )) {
// Successfully retrieved the user name using ANSI 
version, convert it to a string

return to!string(userNameA);
}

// Both GetUserNameW and GetUserNameA failed, return an empty 
string

return "";
}

/**
 * The entry point of the application.
 */
void main(string[] args) {
string username = getSafeUsername();
if (args.length > 1 && args[1] == "print") {
write(username);
} else if (!username.empty){
writeln("Logged-in user name: ", username);

} else {
writeln("Failed to retrieve the user name.");
}
}

```


Windows API: GetUserName: Retrieve the name of the user associated with the current thread.

2023-08-19 Thread BoQsc via Digitalmars-d-learn

I'm sharing some code here.
**It's not completely tested and might contain serious mistakes, 
repetitions, bad style and readabilty.

But it seems to work.**

Critique, improvements and feedback might help.

 Demonstration

This code retrieves username of the current windows user using 
Windows API (Win32).


![img1](https://i.imgur.com/aNyyglu.png)

**WindowsGetUserName.d**
```
import core.sys.windows.windows;
import std.conv;
import std.stdio;
import std.range;

pragma(lib, "advapi32.lib");

/**
 * Retrieves the currently logged-in user's name in a safe manner.
 *
 * This function first determines the required buffer size, 
allocates memory for the username,

 * and then retrieves the username.
 *
 * Returns:
 *   - The username as a string if successful.
 *   - An empty string if an error occurs.
 */
string getSafeUsername() @system {
wchar[] userName;
DWORD userNameSize = 0;

// First, try GetUserNameW (Unicode version)
if (!GetUserNameW(null, )) {
int error = GetLastError();
if (error != ERROR_INSUFFICIENT_BUFFER) {
// Failed for a reason other than an insufficient 
buffer

return "";
}
}

// Allocate memory for userName
scope(exit) userName.length = 0; // Ensure memory is released 
if an exception occurs

userName.length = userNameSize;

// Retrieve the user name by calling GetUserNameW
if (GetUserNameW(userName.ptr, )) {
// Successfully retrieved the user name, convert it to a 
string

return to!string(userName);
}

// If GetUserNameW fails, try GetUserNameA (ANSI version)
char[] userNameA;
userNameSize = 0;

if (!GetUserNameA(null, )) {
int errorA = GetLastError();
if (errorA != ERROR_INSUFFICIENT_BUFFER) {
// Failed for a reason other than an insufficient 
buffer

return "";
}
}

// Allocate memory for userNameA
scope(exit) userNameA.length = 0; // Ensure memory is 
released if an exception occurs

userNameA.length = userNameSize;

// Retrieve the user name by calling GetUserNameA
if (GetUserNameA(userNameA.ptr, )) {
// Successfully retrieved the user name using ANSI 
version, convert it to a string

return to!string(userNameA);
}

// Both GetUserNameW and GetUserNameA failed, return an empty 
string

return "";
}

/**
 * The entry point of the application.
 */
void main() {
string username = getSafeUsername();
if (!username.empty) {
writeln("Logged-in user name: ", username);
} else {
writeln("Failed to retrieve the user name.");
}
}

```


Footnotes
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamea
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getusernamew
https://github.com/dlang/dmd/blob/master/druntime/src/core/sys/windows/winbase.d#L1903-L1904