char * program_name = "Remove TS Licenses"; // messagebox title
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
LONG error_code;
stringstream error_message;
// is the user sure they want to do this?
if (IDYES==MessageBox(NULL, "This program will clear the Terminal Server licenses on this computer. Continue?", program_name, MB_YESNO))
{
HKEY hreg = NULL;
// try opening the license store
error_code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\MSLicensing\\Store", 0, KEY_READ, &hreg);
if (ERROR_SUCCESS!=error_code)
{
// display error message upon failure
error_message << "There was an error opening the license store! (error ROKE:" << error_code << ")";
MessageBox(NULL, error_message.str().c_str(), program_name, MB_ICONERROR);
return 1;
}
// get length of longest subkey name so we can allocate the correct sized buffer
DWORD subkey_buffer_length;
if (ERROR_SUCCESS!=(error_code=RegQueryInfoKey(hreg, NULL, NULL, NULL, NULL, &subkey_buffer_length, NULL, NULL, NULL, NULL, NULL, NULL)))
{
// display error message upon failure
error_message << "There was an error reading information from the license store! (error RQIK:" << error_code << ")";
MessageBox(NULL, error_message.str().c_str(), program_name, MB_ICONERROR);
return 2;
}
subkey_buffer_length++; // +1 for terminating null
char * subkey_buffer = new char[subkey_buffer_length];
int subkeys_deleted;
// enumerate subkeys (i.e. the licenses)
for(subkeys_deleted=0;;subkeys_deleted++)
{
// we continually look for subkey zero as it renumbers them after each deletion
error_code = RegEnumKey(hreg, 0, subkey_buffer, subkey_buffer_length);
if (ERROR_NO_MORE_ITEMS==error_code) // no more licenses to delete, so exit loop
break;
if (ERROR_SUCCESS!=error_code)
{
// display error message upon failure
error_message << "There was an error reading information from the license store! (error REKE:" << subkeys_deleted << ":" << error_code << ")";
MessageBox(NULL, error_message.str().c_str(), program_name, MB_ICONERROR);
return 3;
}
// delete the license we just found
if (ERROR_SUCCESS!=(error_code = SHDeleteKey(hreg, subkey_buffer)))
{
// display error message upon failure
error_message << "There was an error deleting a license from the license store! (error SHDK:" << subkey_buffer << ":" << error_code << ")";
MessageBox(NULL, error_message.str().c_str(), program_name, MB_ICONERROR);
return 4;
}
}
// success!
if (0==subkeys_deleted) // did we actually remove any?
{
MessageBox(NULL, "There were no licenses to remove!", program_name, MB_ICONINFORMATION);
}
else
{
MessageBox(NULL, "All licenses were removed successfully", program_name, MB_ICONINFORMATION);
}
}
return 0;
}
Name:
Anonymous2007-05-16 18:41 ID:ns98HB0Q
in after NULL
Name:
Anonymous2007-05-16 18:52 ID:gaL/NeyG
I find the verbose nature of C++ coders far more annoying. You should also just compile with warnings instead of putting constants on the left side of comparisons.
Name:
Anonymous2007-05-17 5:43 ID:v4Wh9Z4V
You should also just compile with warnings instead of putting constants on the left side of comparisons.
Why?
Name:
Anonymous2007-05-17 6:25 ID:7UXp1b2D
It's like top posting. You should also just compile with warnings instead of putting constants on the left side of comparisons. Why?
There's a special place in Hell for top posters, people who send HTML email/news and coders who write non-idiomatic code. "0 == x" is not idiomatic, check out K&R.
I thought you said a special place in Haskell at first.
Name:
Anonymous2007-05-17 12:39 ID:QWYnadyF
>>12
Not that I disagree, but why use K&R as a style reference for any language but C? (Except to piss off people that force you to write Java.)
Name:
Anonymous2007-05-17 13:13 ID:v4Wh9Z4V
You guys are talking rubbish.
Firstly, putting the constant on the left avoids bugs from mistyping the equality operator as the assignment operator, simply because equality is symmetric but assignment isn't. Yes, I know most modern compilers will emit warnings but it hasn't always been that way.
And secondly, for code like this:
if (constant==very_long_function(with,lots,and,lots,and,lots,of,parameters) {
...
}
it makes sense to put the constant on the left because it's a lot more readable.
I mentioned K&R because >>7 was talking about C. For C++ I'd tell people to write code the way it's printed in Stroustrup's TC++PL instead, Sun's style guide for Java, etc.
if you pass around the singleton then you can actually use to make all of my life in manuals and documentation to have a twat like you asking him to hax someone else instead of using the famed SICP textbook.
Bringing /prog/ back to its people
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy