I have written a function MakeHashKeyFromFileKey16_FIRST() which works fine. Then I replaced Context_ws in line 6 of MakeHashKeyFromFileKey16_SECOND(). Suddenly my code does not work correctly.
Can anybody give me a hint as to why that is?
typedef wchar_t KMX_WCHART;
typedef uint16_t* PKMX_WCHAR ;
std::wstring MakeHashKeyFromFileKey16_FIRST(PFILE_KEY kp) {
std::wstringstream Key_16;
std::wstring Context_ws = u16fmt((const PKMX_WCHAR) kp->dpContext);
Key_16 << conv_KMX_WCHAR__TO__WCHAR(kp->Key) << "," << (DWORD) kp->ShiftFlags << ",";
if ((KMX_WCHART*) Context_ws.c_str()) Key_16 << (KMX_WCHART*) Context_ws.c_str();
return Key_16.str();
};
std::wstring MakeHashKeyFromFileKey16_SECOND(PFILE_KEY kp) {
std::wstringstream Key_16;
std::wstring Context_ws = u16fmt((const PKMX_WCHAR) kp->dpContext);
Key_16 << conv_KMX_WCHAR__TO__WCHAR(kp->Key) << "," << (DWORD) kp->ShiftFlags << ",";
if ((KMX_WCHART*) u16fmt((const PKMX_WCHAR) kp->dpContext).c_str()) Key_16 << (KMX_WCHART*) u16fmt((const PKMX_WCHAR) kp->dpContext).c_str();
return Key_16.str();
};
Related
Actually i am trying to extract RGB value from COLORREF but not getting Value in range of 0 to 255. Instead of that i am getting some string always. eg:0000017153665268
i used below method:
COLORREF obj_Colorref = obj_CColorDialog.GetColor();
RGBTRIPLE rgb;
rgb.rgbtRed = GetRValue(obj_Colorref);
rgb.rgbtGreen = GetGValue(obj_Colorref);
rgb.rgbtBlue = GetBValue(obj_Colorref);
CString sRed;
CString sGreen;
CString sBlue;
sRed.Format(L"%d", rgb.rgbtRed);
sGreen.Format(L"%d", rgb.rgbtGreen);
sBlue.Format(L"%d", rgb.rgbtBlue);
std::ofstream file;
file.open("..//Projects//Ribbon//x64//color.txt");
file << "#"<<"\n"<<"#"<< sRed << ",";
file << sGreen << ",";
file << sBlue << ",";
please help me out.
The problem is with this:
file << "#"<<"\n"<<"#"<< sRed << ",";
file << sGreen << ",";
file << sBlue << ",";
It prints wchar_t based CString to char-based stream.
wchar_t* does not print as string into basic_ostream<char>.
Easiest way to fix is probably to avoid CString altogether:
file << std::to_string((int)rgb.rgbtBlue) << ",";
Or maybe even:
file << (int)rgb.rgbtBlue << ",";
This C# code:
string code_verifier = "xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE";
byte[] sha256verifier = sha256(code_verifier);
string code_challenge = base64urlencodeNoPadding(sha256verifier);
StringBuilder builder = new StringBuilder();
for (int i = 0; i < sha256verifier.Length; i++)
builder.Append(sha256verifier[i].ToString("x2"));
output("code_verifier: " + code_verifier);
output("builder: " + builder.ToString());
output("code_challenge: " + code_challenge);
Produces these results:
code_verifier: xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE
builder: 8b6526951bf46153a9a276be579ee1070f86e0812fbde8b8c37a3e64c3368525
code_challenge: i2UmlRv0YVOpona-V57hBw-G4IEvvei4w3o-ZMM2hSU
I'm trying to do the same in C++ using poco, here's my code:
std::string verifier_ = "xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE";
std::string sha256verifier = sha256(verifier_);
std::stringstream ss;
Poco::Base64Encoder b64enc(ss, Poco::BASE64_URL_ENCODING || Poco::BASE64_NO_PADDING);
b64enc << sha256(sha256verifier);
std::string challenge = ss.str();
cout << "verifier: " << verifier_ << endl;
cout << "sha256verifier: " << sha256verifier << endl;
cout << "challenge: " << challenge << endl;
The result is:
verifier: xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE
sha256verifier: 8b6526951bf46153a9a276be579ee1070f86e0812fbde8b8c37a3e64c3368525
challenge: YTIzY2U1YTYxY2IwMTU0ZmFhZjU1ZWY2ZDEyNGYzZjE3MjQzN2M1MTExNmRiZTY1ZDU1ZTc1NWY2ZjMyNjZi
The C# sha256() function returns a 32 element byte array which base64urlencodeNoPadding converts into a 32 character string.
The C++ sha256() function returns a 32 element hex encoded string of the same data which Poco::Base64Encoder turns into a 64 element string which bears no relation to the C# string.
How can I get the same results from C++ as I get from C# ?
This is my poco sha256 function
std::string::sha256(std::string buffer) {
Poco::Crypto::RSAKey key(Poco::Crypto::RSAKey::KL_2048,
Poco::Crypto::RSAKey::EXP_LARGE);
Poco::Crypto::RSADigestEngine eng(key, "SHA256");
eng.update(buffer.c_str(), buffer.size());
const auto& sig = eng.digest(); // We just want the digest, unsigned.
return Poco::DigestEngine::digestToHex(sig);
}
There are 2 issues in your C++ solution:
you do SHA-256 twice - at sha256(verifier_) and sha256(sha256verifier)
Poco::DigestEngine::digestToHex converts the SHA-256 sum into a Hex string
Try something like this instead (untested):
std::string verifier_ = "xe-V-ykFyCazK3jCWwqRCZHKAKJ0MqdZs8F6xenxjFE";
auto sha256verifier = sha256(verifier_);
std::string challenge = toBase64(sha256verifier);
cout << "verifier: " << verifier_ << endl;
cout << "sha256verifier: " << toHex(sha256verifier) << endl;
cout << "challenge: " << challenge << endl;
std::vector<unsigned char> sha256(std::string const& buffer) {
Poco::Crypto::RSAKey key(Poco::Crypto::RSAKey::KL_2048, Poco::Crypto::RSAKey::EXP_LARGE);
Poco::Crypto::RSADigestEngine eng(key, "SHA256");
eng.update(buffer.c_str(), buffer.size());
return eng.digest();
}
std::string toBase64(std::vector<unsigned char> const& sig) {
std::stringstream ss;
Poco::Base64Encoder b64enc(ss, Poco::BASE64_URL_ENCODING || Poco::BASE64_NO_PADDING);
b64enc.write((const char*)sig.data(), sig.size());
b64enc.close();
return ss.str();
}
std::string toHex(std::vector<unsigned char> const& sig) {
return Poco::DigestEngine::digestToHex(sig);
}
// Update the server status xml
string filelocation ("/var/www/html/index.xml");
string firstline ("<server>\n");
string secondline ("\t<current>" + msg.getCount() + "</current>\n");
string thirdline ("\t<highest>" + "--" + "</highest>\n");
string fourthline ("\t<status>Online</status>\n")
string finalline ("</server>");
fstream file;
file.open(filelocation);
file.write(firstline + secondline + thirdline + fourthline + finalline);
string updateFlush ("Server Status updated.");
printf("%s\n", updateFlush);
file.close();
Note that msg.getCount() is a function in the same file to get player count from the central server.
Gives out errors about an operands const char*. Something to do with + or -
Thanks
Take a look at the line
string secondline ("\t<current>" + msg.getCount() + "</current>\n");
"\t<current>" is a const char *
msg.getCount() looks like an int or size_t
</current>\n again is a const char *
Adding a const char * to an int or size_t creates a new const char * pointing to a different address.
The same happens in the line
string thirdline ("\t<highest>" + "--" + "</highest>\n");
Here you are adding pointers together. The result is a pointer pointing to a more or less random address.
And in these two lines:
string updateFlush ("Server Status updated.");
printf("%s\n", updateFlush);
You are creating a C++ string-object and trying to print it using a C print function with a format string that requires a char *.
You are mixing C and C++ or stream based I/O with conventional I/O.
In current C++ you should do it this way:
string filelocation ("/var/www/html/index.xml");
fstream file;
file.open(filelocation);
file
<< "<server>\n"
<< "\t<current>" << msg.getCount() << "</current>\n"
<< "\t<highest>" << "--" << "</highest>\n"
<< "\t<status>Online</status>\n"
<< "</server>";
string updateFlush ("Server Status updated.");
cout << updateFlush << std::endl;
file.close();
Or even more readable:
auto file = std::ofstream("/var/www/html/index.xml");
file
<< "<server>" << std::endl
<< "\t<current>" << msg.getCount() << "</current>" << std::endl
<< "\t<highest>" << "--" << "</highest>" << std::endl
<< "\t<status>Online</status>" << std::endl
<< "</server>";
file.close();
std::cout << "Server status updated." << std::endl;
If operating with streams use std::endl to output a newline. It outputs the correct newline for the operation system (CRLF or LF or whatever) and it flushes the stream.
To use std::cout you have to include <iostream> and for std::ofstream include <fstream>.
If you like it short, you could even do this:
std::ofstream("/var/www/html/index.xml")
<< "<server>" << std::endl
<< "\t<current>" << msg.getCount() << "</current>" << std::endl
<< "\t<highest>" << "--" << "</highest>" << std::endl
<< "\t<status>Online</status>" << std::endl
<< "</server>";
std::cout << "Server status updated." << std::endl;
I have this code:
std::wstringstream outstream;
outstream << (prop.m_pwszOriginalVolumeName
? prop.m_pwszOriginalVolumeName
: L"null") << L";"
<< (prop.m_pwszSnapshotDeviceObject
? prop.m_pwszSnapshotDeviceObject
: L"null") << L";"
<< (prop.m_pwszOriginatingMachine
? prop.m_pwszOriginatingMachine
: L"null") << L";"
<< ... // some more strings here
Is there a way to avoid code duplication and still have concise code?
You could define a small function:
whatever_t strOrNull(whatever_t str) {
return str ? str : L"null";
}
Then your code becomes
std::wstringstream outstream;
outstream << strOrNull(prop.m_pwszOriginalVolumeName) << L";"
<< strOrNull(prop.m_pwszSnapshotDeviceObject) << L";"
<< strOrNull(prop.m_pwszOriginatingMachine) << L";"
<< ... // some more strings here
Or if you wanted to be even more concise, you could do this (depending on what whatever_t is; if wstringstream already has an operator<< overload for that type, this won't work):
wstringstream& operator<<(wstringstream& out, whatever_t str) {
if (str)
out << str;
else
out << L"null";
return out;
}
Then your code becomes
std::wstringstream outstream;
outstream << prop.m_pwszOriginalVolumeName << L";"
<< prop.m_pwszSnapshotDeviceObject << L";"
<< prop.m_pwszOriginatingMachine << L";"
<< ... // some more strings here
A function, or a lambda:
auto foo = [](const wchar * p) { return p ? p : L"null;" };
outstream << foo(prop.m_pwszOriginalVolumeName) << L";"
<< foo(prop.m_pwszSnapshotDeviceObject) << L";"
<< ...etc...
The other examples are really good. There is another option, though I wouldn't recommend it (only mentioning for completeness).
GCC has an extension called "Conditionals with Omitted Operands" Which basically looks like this:
x = a ?: b;
which is the same as (in simple cases like yours, see below for more info):
x = a ? a : b;
Just less portable. So you could write:
std::wstringstream outstream;
outstream << (prop.m_pwszOriginalVolumeName ?: L"null") << L";"
<< (prop.m_pwszSnapshotDeviceObject ?: L"null") << L";"
<< (prop.m_pwszOriginatingMachine ?: L"null") << L";"
But like I said, I would not recommend this, I would use a helper function like the other answers mention.
There actually is a case where it performs differently than a regular ternary if, and that's if evaluating a has side effects. From the page:
In this simple case, the ability to omit the middle operand is not
especially useful. When it becomes useful is when the first operand
does, or may (if it is a macro argument), contain a side effect. Then
repeating the operand in the middle would perform the side effect
twice. Omitting the middle operand uses the value already computed
without the undesirable effects of recomputing it.
See http://gcc.gnu.org/onlinedocs/gcc/Conditionals.html
A simple function should do the trick.
wchar_t* filterNullString(wchar_t* str)
{
static wchar const* nullStr = L"null";
return str ? str : nullStr;
}
std::wstringstream outstream;
outstream << filterNullString(prop.m_pwszOriginalVolumeName) << L";"
<< filterNullString(prop.m_pwszSnapshotDeviceObject)<< L";"
<< filterNullString(prop.m_pwszOriginatingMachine)<< L";" ;
You could use a helper function:
const wchar_t *SafeOutput(const wchar_t *str)
{
return str ? str : L"null";
}
// Analogous function for ANSI strings
...
outstream << SafeOutput(prop.m_pwszOriginalVolumeName) << L";"
<< SafeOutput(prop.m_pwszSnapshotDeviceObject) << L";"
<< SafeOutput(prop.m_pwszOriginatingMachine) << L";"
<< ... // more strings here
I need to create a GUID in an unmanaged windows C++ project. I'm used to C#, where I'd use Guid.NewGuid(). What's the (unmanaged windows) C++ version?
I think CoCreateGuid is what you're after. Example:
GUID gidReference;
HRESULT hCreateGuid = CoCreateGuid( &gidReference );
UuidCreate() in Win32 API has exactly the same effect. However you need to pass an address of the variable that will receive the generated value:
UUID newId;
UuidCreate( &newId );
I believe Guid.NewGuid() simply maps onto it inside the .NET runtime.
Here's a snippet of code to get the resulting string value of the generated GUID:
// For UUID
#include <Rpc.h>
#pragma comment(lib, "Rpcrt4.lib")
int _tmain(int argc, _TCHAR* argv[])
{
// Create a new uuid
UUID uuid;
RPC_STATUS ret_val = ::UuidCreate(&uuid);
if (ret_val == RPC_S_OK)
{
// convert UUID to LPWSTR
WCHAR* wszUuid = NULL;
::UuidToStringW(&uuid, (RPC_WSTR*)&wszUuid);
if (wszUuid != NULL)
{
//TODO: do something with wszUuid
// free up the allocated string
::RpcStringFreeW((RPC_WSTR*)&wszUuid);
wszUuid = NULL;
}
else
{
//TODO: uh oh, couldn't convert the GUID to string (a result of not enough free memory)
}
}
else
{
//TODO: uh oh, couldn't create the GUID, handle this however you need to
}
return 0;
}
API reference:
UuidCreate
UuidToString
RpcStringFree
The documentation for Guid.NewGuid points out, how it is implemented:
This is a convenient static method that you can call to get a new Guid. The method wraps a call to the Windows CoCreateGuid function.
So the native equivalent to Guid.NewGuid() is CoCreateGuid().
CoCreateGuid calls UuidCreate, to generate a GUID. Both API calls are slightly different, though: While UuidCreate returns a UUID, that is guaranteed to be unique to the computer that created it, CoCreateGuid produces a GUID that is absolutely unique.
If you need to decide, which API to use, here are the relevant sections from the documentation.
UuidCreate:
For security reasons, it is often desirable to keep ethernet addresses on networks from becoming available outside a company or organization. The UuidCreate function generates a UUID that cannot be traced to the ethernet address of the computer on which it was generated. It also cannot be associated with other UUIDs created on the same computer.
CoCreateGuid:
The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use CoCreateGuid when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment.
To generate a new guid in windows and get the resulting value as a string.
#include <string>
#include <sstream>
#include <iostream>
#include <windows.h>
#include <iomanip>
int main()
{
GUID guid;
CoCreateGuid(&guid);
std::ostringstream os;
os << std::hex << std::setw(8) << std::setfill('0') << guid.Data1;
os << '-';
os << std::hex << std::setw(4) << std::setfill('0') << guid.Data2;
os << '-';
os << std::hex << std::setw(4) << std::setfill('0') << guid.Data3;
os << '-';
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[0]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[1]);
os << '-';
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[2]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[3]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[4]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[5]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[6]);
os << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(guid.Data4[7]);
std::string s(os.str());
std::cout << s << std::endl;
}
Alternatively, you could use sprintf_s for the string conversion
GUID guid;
CoCreateGuid(&guid);
char guidStr[37];
sprintf_s(
guidStr,
"%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
std::string s(guidStr);
To get in guid in std::string on Windows
#include <Windows.h>
#include <array>
std::string getGUID()
{
std::string result{};
GUID guid;
if (S_OK == CoCreateGuid(&guid))
{
std::array<char, 36> buffer{}; //32 characters of guid + 4 '-' in-between
snprintf(buffer.data(), buffer.size(), "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
result = std::string(buffer.data());
}
return result;
}
In the new WinRT api you can use winrt::Windows::Foundation::GuidHelper::CreateNewGuid() which returns a struct of winrt::guid type. You can later pass it to winrt::to_hstring to get struct of winrt::hstring type, then pass it to winrt::to_string to get std::string type.