WASAPI GetDisplayName returns blank - c++

I am trying to write a program that interfaces with Windows Core Audio and WASAPI. I am having difficulty with the following couple lines.
CComHeapPtr<WCHAR> name;
hr = pAudioSessionControl->GetDisplayName(&name);
if (FAILED(hr)) {
LOG(L"IAudioSessionControl::GetDisplayName() failed: hr = 0x%08x", hr);
return -__LINE__; }
_tprintf(_T("Session Index %d, \"%s\"\n"), i, CString(name));
Outputs:
Session Index 0, "#%SystemRoot%\System32\AudioSrv.Dll,-202"
Session Index 1, ""
Session Index 2, ""
Session Index 3, ""
Press any key to continue . . .
This is with 3 programs all active and making noise. It seems i can see the system sounds program but nothing else.
Thanks for the help.

An idea from another question.
The problem should be about sessions themselves. Most programs never name their sessions, so usually sessions don't have names, and the name shown on audio mixer might be the name of the window title of sessions' owner process.
Using IAudioSessionControl2::GetProcessID and get the window title of the process through other APIs should give a reasonable name similar to the one from audio mixer.

IAudioSessionControl::GetDisplayName is proper API and it might return non-empty strings, however you might also see inactive sessions for which the strings are indeed empty. In your case you might hit inactive sessions, error code which you did not provide or otherwise incorrect API use.
This code snippet/application enumerates sessions and polls for volume changes - it prints non-empty strings.
CComHeapPtr<WCHAR> pszDisplayName;
ATLENSURE_SUCCEEDED(pSessionControl->GetDisplayName(&pszDisplayName));
_tprintf(_T("nSessionIndex %d, pszDisplayName \"%s\"\n"),
nSessionIndex, CString(pszDisplayName));
C:\AudioSessionVolumeNotification\Debug>AudioSessionVolumeNotification.exe
nSessionCount 5
nSessionIndex 0, pszDisplayName "#%SystemRoot%\System32\AudioSrv.Dll,-202"
nSessionIndex 1, pszDisplayName "Mozilla Firefox"
nSessionIndex 2, pszDisplayName "Mozilla Thunderbird"
nSessionIndex 3, pszDisplayName "Mozilla Firefox"
nSessionIndex 4, pszDisplayName ""

Related

Why does JetAttachDatabase return error -550?

stack, I need help, JetAttachDatabase returning error -550. JET_paramRecovery is switched off. What should I do that it starts work?
I've already tried to restore instance, but I have no restore file... I don't know what should I do. Now I have code like that
sWebDataBase.err = JetGetDatabaseFileInfo(sWebDataBase.path,
&sWebDataBase.dbPageSize,
sizeof(sWebDataBase.dbPageSize),
JET_DbInfoPageSize);
ErrCheck(sWebDataBase.err, "JetSetSystemParameter, JetGetDatabaseFileInfo");
sWebDataBase.err = JetSetSystemParameter (&sWebDataBase.instance,
JET_sesidNil,
JET_paramDatabasePageSize,
sWebDataBase.dbPageSize,
NULL);
ErrCheck(sWebDataBase.err, "JetSetSystemParameter, JET_paramDatabasePageSize");
sWebDataBase.err = JetSetSystemParameterW(&sWebDataBase.instance,
JET_sesidNil,
JET_paramAlternateDatabaseRecoveryPath,
NULL,
L"C:\\Users\\Chrnykh\\AppData\\Local\\Microsoft\\Windows\\WebCache\\test1.dat");
ErrCheck(sWebDataBase.err, "JetSetSystemParameter, JET_paramAlternateDatabaseRecoveryPath");
sWebDataBase.err = JetSetSystemParameter (&sWebDataBase.instance,
JET_sesidNil,
JET_paramRecovery,
NULL,
(JET_PCWSTR)"On");
ErrCheck(sWebDataBase.err, "JetSetSystemParameter, JET_paramRecovery");
sWebDataBase.err = JetInit (&sWebDataBase.instance); //------------------------------------JetInit
ErrCheck(sWebDataBase.err, "JetInit");
sWebDataBase.err = JetBeginSession (sWebDataBase.instance,
&sWebDataBase.sesId,
NULL,
NULL);
ErrCheck(sWebDataBase.err, "JetBeginSession");
ErrCheck(sWebDataBase.err, "JetRestoreInstanceW");
sWebDataBase.err = JetAttachDatabase(sWebDataBase.sesId,
sWebDataBase.path,
JET_bitDbReadOnly);
ErrCheck(sWebDataBase.err, "JetAttachDatabaseW");
sWebDataBase.err = JetOpenDatabaseW(sWebDataBase.sesId,
sWebDataBase.path,
NULL,
&sWebDataBase.dbId,
JET_bitDbReadOnly);
ErrCheck(sWebDataBase.err, "JetOpenDatabaseW");
You shouldn't have to set JET_paramRecovery. It defaults to on. Try removing that. You also set it to "On" in the code, but your question says it was set off. It's also not a good idea to disable it, because if you modify the database and crash, then the entire database is unusable at that point. This is acceptable for a very small minority of people.
Instead of setting JET_paramAlternateDatabaseRecoveryPath, you should set the Logging path.
When you call JetInit, the database engine will examine the current log stream, and replay the operations if necessary. You'll need to set the logging directory, as well as the Checkpoint file location (confusingly called "System Path"). Then it should be able to replay the log files successfully. You may also need to set the "Log file base name", which defaults to "edb", but it can be set to any 3-character sequence.
You can also use the command-line utility esentutl.exe to replay the logs first. Use it by changing in to the directory of the log files, and running a command like esentutl.exe -r edb.
Does that make sense?

Correct usage of sqllite3_bin_text

I'am writing a small application (Login Mask) to get comfortable with the usage of SQLite3.
Right now I have a problem with the correct usage of sqlite3_bind_text(). I've create a small DB with only 1 row. In this part of the code I would like to bind the user input to a variable and bind it to a statement. The user input delivered is by the getline(cin,variable) function.
My problem:
I get an instant "False Library use" when I try to use the bind method. The result is always 21. I have read the API documentation several times, but I obviously don't understand the last part.
Can someone please show me how to correctly use this function(s)?
I've checked my column types and they are "Text NOT NULL".
int Login::check_login(string username, string password) {
int errcode = 0;
string query = "Select a_username,a_password from t_user where a_username = ? and a_password = ?;";
sqlite3_stmt *createStmt;
errcode = sqlite3_prepare_v2(datab->get_db(), query.c_str(), query.size(), &createStmt, NULL);
if (!errcode)
throw runtime_error("Failed! Can not prepare statement DB.");
errcode = sqlite3_bind_text(createStmt, 1, password.c_str(), -1, SQLITE_STATIC); // Always 21 because of false library use
//there is more code but i think this should be enough
P.S.
I've googled this 2 days and found no solution / easy explanation of my problem.
I think your call to sqlite3_prepare_v2() fails and doesn't prepare valid statement (you don't get exception, don't you?), but there is a typo in error check.
When sqlite3_* function succeeds, it returns SQLITE_OK which is 0. So correct error check is:
if (errcode)
throw runtime_error("Failed! Can not prepare statement DB.");
That is why sqlite3_bind_text() also fails.

How to get Expiration Date of access token in Facebook SDK for Unity

I am using parse sdk for backend management for my game. For user signup/login parse api ask for parameter tokenExpiration. I have no idea how to get it from facebook unity sdk.
https://www.parse.com/docs/unity_guide#fbusers-signup
Task<ParseUser> logInTask = ParseFacebookUtils.LogInAsync(accessToken, userId, tokenExpiration);
Got this problem solved by myself using debug_token. Here is the right code on how to do it.
FB.API("/debug_token?input_token="+FB.AccessToken+"&access_token="+FB.AccessToken,Facebook.HttpMethod.GET, AccessTokenCallback);
function AccessTokenCallback(response:String){
Debug.Log(response);
var access = JSON.Parse(response);
Debug.Log("Token Expiration is: "+access["data"]["expires_at"].Value);
}
If you will print the response it will give you a JSON with all information about the access token and you can take whatever info you need about an access token.
Open FacebookAccessTokenEditor.cs and replace original line 81:
formData["batch"] = "[{\"method\":\"GET\", \"relative_url\":\"me?fields=id\"},{\"method\":\"GET\", \"relative_url\":\"app?fields=id\"}]";
by these two:
string getExpiresAt = ",{\"method\":\"GET\", \"relative_url\":\"debug_token?input_token="+accessToken+"\"}";
formData["batch"] = "[{\"method\":\"GET\", \"relative_url\":\"me?fields=id\"},{\"method\":\"GET\", \"relative_url\":\"app?fields=id\"}"+getExpiresAt+"]";
Then open FacebookEditor.cs and in method MockLoginCallback, just before line 220:
isLoggedIn = true;
insert the following lines:
var tokenData = (Dictionary<string, object>)MiniJSON.Json.Deserialize(responses[2]);
var expiresAt = (long)((Dictionary<string, object>)tokenData["data"])["expires_at"];
accessTokenExpiresAt = FromTimestamp((int)expiresAt);
also, add the missing function FromTimestamp which you can copy from AndroidFacebook.cs or IOSFacebook.cs or jus copy from here:
private DateTime FromTimestamp(int timestamp)
{
return new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(timestamp);
}
Finally, you can call the parse method like you do on IOS or Android or Web:
Task<ParseUser> logInTask = ParseFacebookUtils.LogInAsync(FB.UserId, FB.AccessToken, FB.AccessTokenExpiresAt);
Note: As I have worked on the code, I am not sure of the original line numbers, but I think they are correct. Also, this does not reflect the best coding practices, but since it is used only in a debug context, they're good enough for me.

Finding the phone company of a cell phone number?

I have an application where people can give a phone number and it will send SMS texts to the phone number through EMail-SMS gateways. For this to work however, I need the phone company of the given number so that I send the email to the proper SMS gateway. I've seen some services that allow you to look up this information, but none of them in the form of a web service or database.
For instance, http://tnid.us provides such a service. Example output from my phone number:
Where do they get the "Current Telephone Company" information for each number. Is this freely available information? Is there a database or some sort of web service I can use to get that information for a given cell phone number?
What you need is called a HLR (Home Location Register) number lookup.
In their basic forms such APIs will expect a phone number in international format (example, +15121234567) and will return back their IMSI, which includes their MCC (gives you the country) and MNC (gives you the phone's carrier). The may even include the phone's current carrier (eg to tell if the phone is roaming). It may not work if the phone is currently out of range or turned off. In those cases, depending on the API provider, they may give you a cached result.
The site you mentioned seems to provide such functionality. A web search for "HLR lookup API" will give you plenty more results. I have personal experience with CLX's service and would recommend it.
This would be pretty code intensive, but something you could do right now, on your own, without APIs as long as the tnid.us site is around:
Why not have IE open in a hidden browser window with the URL of the phone number? It looks like the URL would take the format of http://tnid.us/search.php?q=########## where # represents a number. So you need a textbox, a label, and a button. I call the textbox "txtPhoneNumber", the label "lblCarrier", and the button would call the function I have below "OnClick".
The button function creates the IE instance using MSHtml.dll and SHDocVW.dll and does a page scrape of the HTML that is in your browser "object". You then parse it down. You have to first install the Interoperability Assemblies that came with Visual Studio 2005 (C:\Program Files\Common Files\Merge Modules\vs_piaredist.exe). Then:
1> Create a new web project in Visual Studio.NET.
2> Add a reference to SHDocVw.dll and Microsoft.mshtml.
3> In default.aspx.cs, add these lines at the top:
using mshtml;
using SHDocVw;
using System.Threading;
4> Add the following function :
protected void executeMSIE(Object sender, EventArgs e)
{
SHDocVw.InternetExplorer ie = new SHDocVw.InternetExplorerClass();
object o = System.Reflection.Missing.Value;
TextBox txtPhoneNumber = (TextBox)this.Page.FindControl("txtPhoneNumber");
object url = "http://tnid.us/search.php?q=" + txtPhoneNumber.Text);
StringBuilder sb = new StringBuilder();
if (ie != null) {
ie.Navigate2(ref url,ref o,ref o,ref o,ref o);
ie.Visible = false;
while(ie.Busy){Thread.Sleep(2);}
IHTMLDocument2 d = (IHTMLDocument2) ie.Document;
if (d != null) {
IHTMLElementCollection all = d.all;
string ourText = String.Empty;
foreach (object el in all)
{
//find the text by checking each (string)el.Text
if ((string)el.ToString().Contains("Current Phone Company"))
ourText = (string)el.ToString();
}
// or maybe do something like this instead of the loop above...
// HTMLInputElement searchText = (HTMLInputElement)d.all.item("p", 0);
int idx = 0;
// and do a foreach on searchText to find the right "<p>"...
foreach (string s in searchText) {
if (s.Contains("Current Phone Company") || s.Contains("Original Phone Company")) {
idx = s.IndexOf("<strong>") + 8;
ourText = s.Substring(idx);
idx = ourText.IndexOf('<');
ourText = ourText.Substring(0, idx);
}
}
// ... then decode "ourText"
string[] ourArray = ourText.Split(';');
foreach (string s in ourArray) {
char c = (char)s.Split('#')[1];
sb.Append(c.ToString());
}
// sb.ToString() is now your phone company carrier....
}
}
if (sb != null)
lblCarrier.Text = sb.ToString();
else
lblCarrier.Text = "No MSIE?";
}
For some reason I don't get the "Current Phone Company" when I just use the tnid.us site directly, though, only the Original. So you might want to have the code test what it's getting back, i.e.
bool currentCompanyFound = false;
if (s.Contains("Current Telephone Company")) { currentCompanyFound = true }
I have it checking for either one, above, so you get something back. What the code should do is to find the area of HTML between
<p class="lt">Current Telephone Company:<br /><strong>
and
</strong></p>
I have it looking for the index of
<strong>
and adding on the characters of that word to get to the starting position. I can't remember if you can use strings or only characters for .indexOf. But you get the point and you or someone else can probably find a way to get it working from there.
That text you get back is encoded with char codes, so you'd have to convert those. I gave you some code above that should assist in that... it's untested and completely from my head, but it should work or get you where you're going.
Did you look just slightly farther down on the tnid.us result page?
Need API access? Contact sales#tnID.us.
[Disclosure: I work for Twilio]
You can retrieve phone number information with Twilio Lookup.
If you are currently evaluating services and functionality for phone number lookup, I'd suggest giving Lookup a try via the quickstart.

Detect if program is running with full administrator rights

I need to determine if my program is running with full administrator rights. By that I mean if uac is turned on (for win vista/7) that I need to determine if the program actually has admin rights (like if the user right clicked and selected "run as administator") and not limited by uac. How do I do this in C++?
Win9x: Everyone is "admin"
NT4: OpenThreadToken/OpenProcessToken + GetTokenInformation(...,TokenGroups,...) on DOMAIN_ALIAS_RID_ADMINS SID in a loop
2000+: OpenThreadToken/OpenProcessToken + CheckTokenMembership on DOMAIN_ALIAS_RID_ADMINS SID
Other alternatives are: IsUserAnAdmin or AccessCheck
Checking the TOKEN_ELEVATION* stuff in the token is not required for testing the current process but it is useful if you need to find out if the user could elevate because they have a split token etc.
An expansion on Anders' answer for those (like me) who are less Windows literate:
BOOL isMember;
PSID administratorsGroup = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthNT =
SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&administratorsGroup))
{
throw(oops_t(GetLastError(), "AllocateAndInitializeSid"));
}
if (!CheckTokenMembership(nullptr, administratorsGroup, &isMember))
{
throw(oops_t(GetLastError(), "CheckTokenMembership"));
}
if (!isMember)
{
throw(oops_t(ERROR_ACCESS_DENIED, "Test for Admin privileges"));
}