CrerdWriteW storing credentials in Mandarin on Windows - c++

I used the answer here to add credentials programmatically to Windows Credential Manager. The code is inspired by the code in the answer. When I run it however, the credentials in the cred manager show up in Mandarin. I am not sure what am I doing wrong. Would appreciate any pointers. TIA .
For references this is the code I have
#include <iostream>
#include "windows.h"
#include "wincred.h"
#pragma hdrstop
using namespace std;
int main()
{
const char* password = "testpass";
CREDENTIALW creds = { 0 };
creds.Type = CRED_TYPE_GENERIC;
creds.TargetName = (LPWSTR)("testaccount");
creds.CredentialBlobSize = strlen(password) + 1;
creds.CredentialBlob = (LPBYTE)password;
creds.Persist = CRED_PERSIST_LOCAL_MACHINE;
creds.UserName = (LPWSTR)("testuser");
BOOL result = CredWriteW(&creds, 0);
if (result != TRUE)
{
cout << "Some error occurred" << endl;
}
else
{
cout << "Stored the password successfully" << endl;
}
return 0;
}
To ensure there is no default language problem, I manually created a credential from within the credential manager for test.com and had no problems with it. Snapshot of the Cred Manager -

Appearantly, TargetName needs to refer to a mutable array, i.e. not a string literal. It also needs to be a wide string, or else the characters will be interpreted wrongly, in this case resulting in Chinese characters.
The solution is to define a mutable array that is initialized with a wide string, and have TargetName point to it:
WCHAR targetName [] = L"testuser";
creds.TargetName = targetName;
This way, no suspicious cast is needed to make it compile. When you want to input non-hardcoded strings (e.g. from user input or a file), you need to make sure they are correctly encoded and convert appropriately.

Related

In ArduinoJson how can one check if an error occured when creating a JSON document?

In the ArduinoJson library, it is easy to create JSON entries as shown below.
StaticJsonDocument<512> json_doc;
String some_string = "Hello there!";
json_doc["some_string"] = some_string;
The question is what is the best way to check whether the entry was successfully created? This would allow error handling to be implemented and the error to be found quickly if the entries that are created change and grow over time.
Simply test to see whether the added node has a non-null value. If after you've tried to create a node, that node has a null value, the node was not created.
Here's a simple Sketch to illustrate this test:
#include <ArduinoJson.h>
StaticJsonDocument<100> json_doc;
int nodeNumber = 0;
boolean ranOut = false;
void setup() {
Serial.begin(9600);
}
void loop() {
if (ranOut) return;
String nodeName(nodeNumber++);
String nodeContent = nodeName + " thing";
json_doc[nodeName] = nodeContent;
if (!json_doc[nodeName]) {
ranOut = true;
Serial.print("Ran out at ");
Serial.println(nodeNumber);
}
}
When I ran this Sketch on my Arduino Uno, it produced:
Ran out at 6
That is, it created successfully created nodes json_doc["0"] through json_doc["5"] and ran out of space when it tried to create json_doc["6"].

findAndGetString() in DCMTK returns null for the tag

I am developing a quick DICOM viewer using DCMTK library and I am following the example provided in this link.
The buffer from the API always returns null for any tag ID, eg: DCM_PatientName.
But the findAndGetOFString() API works fine but returns only the first character of the tag in ASCII, is this how this API should work?
Can someone let me know why the buffer is empty the former API?
Also the DicomImage API also the same issue.
Snippet 1:
DcmFileFormat fileformat;
OFCondition status = fileformat.loadFile(test_data_file_path.toStdString().c_str());
if (status.good())
{
OFString patientName;
char* name;
if (fileformat.getDataset()->findAndGetOFString(DCM_PatientName, patientName).good())
{
name = new char[patientName.length()];
strcpy(name, patientName.c_str());
}
else
{
qDebug() << "Error: cannot access Patient's Name!";
}
}
else
{
qDebug() << "Error: cannot read DICOM file (" << status.text() << ")";
}
In the above snippet name has the ASCII value "50" and the actual name is "PATIENT".
Snippet 2:
DcmFileFormat file_format;
OFCondition status = file_format.loadFile(test_data_file_path.toStdString().c_str());
std::shared_ptr<DcmDataset> dataset(file_format.getDataset());
qDebug() << "\nInformation extracted from DICOM file: \n";
const char* buffer = nullptr;
DcmTagKey key = DCM_PatientName;
dataset->findAndGetString(key,buffer);
std::string tag_value = buffer;
qDebug() << "Patient name: " << tag_value.c_str();
In the above snippet, the buffer is null. It doesn't read the name.
NOTE:
This is only a sample. I am just playing around the APIs for learning
purpose.
The following sample method reads the patient name from a DcmDataset object:
std::string getPatientName(DcmDataset& dataset)
{
// Get the tag's value in ofstring
OFString ofstring;
OFCondition condition = dataset.findAndGetOFString(DCM_PatientName, ofstring);
if(condition.good())
{
// Tag found. Put it in a std::string and return it
return std::string(ofstring.c_str());
}
// Tag not found
return ""; // or throw if you need the tag
}
I have tried your code with your datasets. I just replaced the output to QT console classes to std::cout. It works for me - i.e. it prints the correct patient name (e.g. "PATIENT2" for scan2.dcm). Everything seems correct, except for the fact that you apparently want to transfer the ownership for the dataset to a smart pointer.
To obtain the ownership for the DcmDataset from the DcmFileFormat, you must call getAndRemoveDataset() instead of getDataset(). However, I do not think that your issue is related that. You may want to try my modified snippet:
DcmFileFormat file_format;
OFCondition status = file_format.loadFile("d:\\temp\\StackOverflow\\scan2.dcm");
std::shared_ptr<DcmDataset> dataset(file_format.getAndRemoveDataset());
std::cout << "\nInformation extracted from DICOM file: \n";
const char* buffer = nullptr;
DcmTagKey key = DCM_PatientName;
dataset->findAndGetString(key, buffer);
std::string tag_value = buffer;
std::cout << "Patient name: " << tag_value.c_str();
It probably helps you to know that your code and the dcmtk methods you use are correct, but that does not solve your problem. Another thing I would recommend is to verify the result returned by file_format.loadFile(). Maybe there is a surprise in there.
Not sure if I can help you more, but my next step would be to verify your build environment, e.g. the options that you use for building dcmtk. Are you using CMake to build dcmtk?

How to get protobuf enum as string?

Is it possible to obtain the string equivalent of protobuf enums in C++?
e.g.:
The following is the message description:
package MyPackage;
message MyMessage
{
enum RequestType
{
Login = 0;
Logout = 1;
}
optional RequestType requestType = 1;
}
In my code I wish to do something like this:
MyMessage::RequestType requestType = MyMessage::RequestType::Login;
// requestTypeString will be "Login"
std::string requestTypeString = ProtobufEnumToString(requestType);
The EnumDescriptor and EnumValueDescriptor classes can be used for this kind of manipulation, and the
the generated .pb.h and .pb.cc names are easy enough to read, so you can look through them to get details on the functions they offer.
In this particular case, the following should work (untested):
std::string requestTypeString = MyMessage_RequestType_Name(requestType);
See the answer of Josh Kelley, use the EnumDescriptor and EnumValueDescriptor.
The EnumDescriptor documentation says:
To get a EnumDescriptor
To get the EnumDescriptor for a generated enum type, call
TypeName_descriptor(). Use DescriptorPool to construct your own
descriptors.
To get the string value, use FindValueByNumber(int number)
const EnumValueDescriptor * EnumDescriptor::FindValueByNumber(int number) const
Looks up a value by number.
Returns NULL if no such value exists. If multiple values have this >number,the first one defined is returned.
Example, get the protobuf enum:
enum UserStatus {
AWAY = 0;
ONLINE = 1;
OFFLINE = 2;
}
The code to read the string name from a value and the value from a string name:
const google::protobuf::EnumDescriptor *descriptor = UserStatus_descriptor();
std::string name = descriptor->FindValueByNumber(UserStatus::ONLINE)->name();
int number = descriptor->FindValueByName("ONLINE")->number();
std::cout << "Enum name: " << name << std::endl;
std::cout << "Enum number: " << number << std::endl;

how to get all timezone names in ICU

I am using boost::locale with ICU Backend to do time conversion between different timezones.when creating boost::local::Calendar, I can pass in a string like "America/New_York" to specify the timezone information.
but how do I get a list of all valid timezone names?
from ICU doc, it mentioned that users can use TimeZone.getAvailableIDs() method to iterate through all timezone names. but I can't even find a method called getAvailableIDs in timezone.h.
you can use TimeZone.createEnumeration() to get a list of all timezone names. it does says in the doc that using getAvailabeIDs, but this method seems not exist anymore.
I managed to implement it like this, using ICU 4.4.2:
#include <iostream>
#include <unicode/timezone.h>
#include <unicode/unistr.h>
using namespace icu;
int main()
{
StringEnumeration *timeZoneIds = TimeZone::createEnumeration();
UErrorCode status = U_ZERO_ERROR;
const UnicodeString *zoneId = timeZoneIds->snext(status);
while (zoneId != NULL && status == U_ZERO_ERROR)
{
std::string zoneIdString;
zoneId->toUTF8String(zoneIdString);
std::cout << zoneIdString << std::endl;
zoneId = timeZoneIds->snext(status);
}
delete timeZoneIds;
return 0;
}

How to determine if the process owner is an administrator on Mac OS X in C++

How do I programmatically check if the user that ran my executable is an administrator?
This is C++ on Mac OS X 10.6 (Snow Leopard) or higher. My many searches have not turned up anything.
Check the groups that the user is in, and confirm that the user is in the required group. I think you want to check that the user belongs to 'admin', but you may instead want to check for other, more specific access. Why do you want to check for admin anyway? It's usually a better idea to directly attempt the task, than to check for a broad level of access and failing if the user doesn't have that access, but does infact have the specific access you want.
#include <grp.h>
#include <pwd.h>
#include <string.h>
bool currentUserIsAdmin ( ) {
// A user cannot be member in more than NGROUPS groups,
// not counting the default group (hence the + 1)
gid_t groupIDs[NGROUPS + 1];
// ID of user who started the process
uid_t userID = getuid();
// Get user password info for that user
struct passwd * pw = getpwuid(userID);
int groupCount;
if (pw) {
// Look up groups that user belongs to
groupCount = NGROUPS + 1;
// getgrouplist returns ints and not gid_t and
// both may not necessarily have the same size
int intGroupIDs[NGROUPS + 1];
getgrouplist(pw->pw_name, pw->pw_gid, intGroupIDs, &groupCount);
// Copy them to real array
for (int i = 0; i < groupCount; i++) groupIDs[i] = intGroupIDs[i];
} else {
// We cannot lookup the user but we can look what groups this process
// currently belongs to (which is usually the same group list).
groupCount = getgroups(NGROUPS + 1, groupIDs);
}
for (int i = 0; i < groupCount; i++) {
// Get the group info for each group
struct group * group = getgrgid(groupIDs[i]);
if (!group) continue;
// An admin user is member of the group named "admin"
if (strcmp(group->gr_name, "admin") == 0) return true;
}
return false;
}
How about checking a user id by calling getuid()? OS X is based on BSD. Thus, I think you might be able to check what ID runs the process by this function.
It looks like Open Directory is the proper way to do this. You might be able to cheap it out by using getegid() and/or setegid()
I haven't tested it but this might work:
// 80 should be the admin group number, but it Apple might change it in a later release.
if (getegid() == 80 || setegid(80) == 0) {
// Yea! I'm an admin.
}
Just a couple of quick ideas to follow up on. I hope they lead you in the right direction.