Add -d/--debug option for windows plugins

#fixes 8119
This commit is contained in:
Jean Flach 2015-01-12 15:53:25 +01:00
parent 98989719ee
commit c11f2d5ca2
10 changed files with 431 additions and 103 deletions

View File

@ -34,6 +34,8 @@ namespace po = boost::program_options;
using std::cout; using std::endl; using std::set;
using std::vector; using std::wstring; using std::wcout;
static BOOL debug = FALSE;
struct drive
{
wstring name;
@ -100,6 +102,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print usage message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("warning,w", po::wvalue<wstring>(), "warning threshold")
("critical,c", po::wvalue<wstring>(), "critical threshold")
("path,p", po::wvalue<vector<std::wstring>>()->multitoken(), "declare explicitly which drives to check (default checks all)")
@ -196,11 +199,16 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
} else
printInfo.unit = BunitB;
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(printInfoStruct& printInfo, vector<drive>& vDrives)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
double tCap = 0, tFree = 0;
std::wstringstream perf, prePerf;
@ -233,13 +241,13 @@ int printOutput(printInfoStruct& printInfo, vector<drive>& vDrives)
switch (state) {
case OK:
wcout << L"DISK OK " << tFree << unit << prePerf.str() << perf.str() << endl;
wcout << L"DISK OK " << std::fixed << removeZero(tFree) << unit << prePerf.str() << perf.str() << endl;
break;
case WARNING:
wcout << L"DISK WARNING " << tFree << unit << prePerf.str() << perf.str() << endl;
wcout << L"DISK WARNING " << std::fixed << removeZero(tFree) << unit << prePerf.str() << perf.str() << endl;
break;
case CRITICAL:
wcout << L"DISK CRITICAL " << tFree << unit << prePerf.str() << perf.str() << endl;
wcout << L"DISK CRITICAL " << std::fixed << removeZero(tFree) << unit << prePerf.str() << perf.str() << endl;
break;
}
@ -249,29 +257,45 @@ int printOutput(printInfoStruct& printInfo, vector<drive>& vDrives)
int check_drives(vector<drive>& vDrives)
{
DWORD dwResult, dwSize = 0, dwVolumePathNamesLen = MAX_PATH + 1;
wchar_t szLogicalDrives[MAX_PATH], szVolumeName[MAX_PATH], *szVolumePathNames;
wchar_t szLogicalDrives[1024], szVolumeName[MAX_PATH], *szVolumePathNames;
HANDLE hVolume;
wstring wsLogicalDrives;
size_t volumeNameEnd = 0;
set<wstring> sDrives;
if (debug)
wcout << L"Getting logic drive string (includes network drives)" << endl;
dwResult = GetLogicalDriveStrings(MAX_PATH, szLogicalDrives);
if (dwResult < 0 || dwResult > MAX_PATH)
goto die;
if (debug)
wcout << L"Splitting string into single drive names" << endl;
LPTSTR szSingleDrive = szLogicalDrives;
while (*szSingleDrive) {
wstring drname = szSingleDrive;
sDrives.insert(drname);
szSingleDrive += wcslen(szSingleDrive) + 1;
if (debug)
wcout << "Got: " << drname << endl;
}
if (debug)
wcout << L"Getting volume mountpoints (includes NTFS folders)" << endl
<< L"Getting first volume" << endl;
hVolume = FindFirstVolume(szVolumeName, MAX_PATH);
if (hVolume == INVALID_HANDLE_VALUE)
goto die;
if (debug)
wcout << L"Traversing through list of drives" << endl;
while (GetLastError() != ERROR_NO_MORE_FILES) {
if (debug)
wcout << L"Path name for " << szVolumeName << L"= \"";
volumeNameEnd = wcslen(szVolumeName) - 1;
szVolumePathNames = reinterpret_cast<wchar_t*>(new WCHAR[dwVolumePathNamesLen]);
@ -282,17 +306,25 @@ int check_drives(vector<drive>& vDrives)
szVolumePathNames = reinterpret_cast<wchar_t*>(new WCHAR[dwVolumePathNamesLen]);
}
wcout << szVolumePathNames << L"\"" << endl;
//.insert() does the dublicate checking
sDrives.insert(wstring(szVolumePathNames));
FindNextVolume(hVolume, szVolumeName, MAX_PATH);
}
wcout << L"Creating vector from found volumes, removing cd drives etc.:" << endl;
for (set<wstring>::iterator it = sDrives.begin(); it != sDrives.end(); ++it) {
UINT type = GetDriveType(it->c_str());
if (type == DRIVE_FIXED || type == DRIVE_REMOTE) {
if (debug)
wcout << L"\t" << *it << endl;
vDrives.push_back(drive(*it));
}
}
FindVolumeClose(hVolume);
delete[] reinterpret_cast<wchar_t*>(szVolumePathNames);
return -1;
die:
@ -306,15 +338,19 @@ int check_drives(vector<drive>& vDrives, printInfoStruct& printInfo)
{
wchar_t *slash = L"\\";
if (debug)
wcout << L"Parsing user input drive names" << endl;
for (vector<wstring>::iterator it = printInfo.drives.begin();
it != printInfo.drives.end(); ++it) {
if (it->at(it->length() - 1) != *slash)
it->append(slash);
if (std::wstring::npos == it->find(L":\\")) {
wcout << "A \":\" is required after the drive name of " << *it << endl;
return 3;
}
if (debug)
wcout << L"Added " << *it << endl;
vDrives.push_back(drive(*it));
}
return -1;
@ -322,13 +358,21 @@ int check_drives(vector<drive>& vDrives, printInfoStruct& printInfo)
bool getFreeAndCap(drive& drive, const Bunit& unit)
{
if (debug)
wcout << L"Getting free disk space for drive " << drive.name << endl;
ULARGE_INTEGER tempFree, tempTotal;
if (!GetDiskFreeSpaceEx(drive.name.c_str(), NULL, &tempTotal, &tempFree)) {
return FALSE;
}
if (debug)
wcout << L"\tcap: " << tempFree.QuadPart << endl;
drive.cap = round((tempTotal.QuadPart / pow(1024.0, unit)));
if (debug)
wcout << L"\tAfter converion: " << drive.cap << endl
<< L"\tfree: " << tempFree.QuadPart << endl;
drive.free = round((tempFree.QuadPart / pow(1024.0, unit)));
if (debug)
wcout << L"\tAfter converion: " << drive.free << endl << endl;
return TRUE;
}

View File

@ -33,6 +33,8 @@ namespace po = boost::program_options;
using std::endl; using std::cout; using std::wstring;
using std::wcout;
static BOOL debug = FALSE;
struct printInfoStruct
{
threshold warn, crit;
@ -69,6 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print usage message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("warning,w", po::wvalue<wstring>(), "warning value (in percent)")
("critical,c", po::wvalue<wstring>(), "critical value (in percent)")
;
@ -156,11 +159,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
}
}
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
if (printInfo.warn.rend(printInfo.load))
@ -199,6 +208,9 @@ int check_load(printInfoStruct& printInfo)
LPCWSTR path = L"\\Processor(_Total)\\% Idle Time";
if (debug)
wcout << L"Creating query and adding counter" << endl;
err = PdhOpenQuery(NULL, NULL, &phQuery);
if (!SUCCEEDED(err))
goto die;
@ -207,20 +219,39 @@ int check_load(printInfoStruct& printInfo)
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Collecting first batch of query data" << endl;
err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Sleep for one second" << endl;
Sleep(1000);
if (debug)
wcout << L"Collecting second batch of query data" << endl;
err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Creating formatted counter array" << endl;
err = PdhGetFormattedCounterValue(phCounter, PDH_FMT_DOUBLE, &CounterType, &DisplayValue);
if (SUCCEEDED(err)) {
if (DisplayValue.CStatus == PDH_CSTATUS_VALID_DATA)
if (DisplayValue.CStatus == PDH_CSTATUS_VALID_DATA) {
if (debug)
wcout << L"Recieved Value of " << DisplayValue.doubleValue << L" (idle)" << endl;
printInfo.load = 100.0 - DisplayValue.doubleValue;
}
if (debug)
wcout << L"Finished collection. Cleaning up and returning" << endl;
PdhCloseQuery(phQuery);
return -1;
}

View File

@ -31,6 +31,9 @@ namespace po = boost::program_options;
using std::endl; using std::vector; using std::wstring;
using std::wcout; using std::cout;
static BOOL debug = FALSE;
struct nInterface
{
wstring name;
@ -77,6 +80,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print usage and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("warning,w", po::wvalue<wstring>(), "warning value")
("critical,c", po::wvalue<wstring>(), "critical value")
;
@ -161,11 +165,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
}
}
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(printInfoStruct& printInfo, const vector<nInterface>& vInterfaces)
{
if (debug)
wcout << L"Constructing output string" << endl;
long tIn = 0, tOut = 0;
std::wstringstream tss, perfDataFirst;
state state = OK;
@ -209,6 +219,9 @@ int check_network(vector <nInterface>& vInterfaces)
PDH_FMT_COUNTERVALUE_ITEM *pDisplayValuesIn = NULL, *pDisplayValuesOut = NULL;
PDH_STATUS err;
if (debug)
wcout << L"Creating Query and adding counters" << endl;
err = PdhOpenQuery(NULL, NULL, &phQuery);
if (!SUCCEEDED(err))
goto die;
@ -221,16 +234,28 @@ int check_network(vector <nInterface>& vInterfaces)
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Collecting first batch of query data" << endl;
err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Sleep for one second" << endl;
Sleep(1000);
if (debug)
wcout << L"Collecting second batch of query data" << endl;
err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Creating formatted counter arrays" << endl;
err = PdhGetFormattedCounterArray(phCounterIn, PDH_FMT_LONG, &dwBufferSizeIn, &dwItemCount, pDisplayValuesIn);
if (err == PDH_MORE_DATA || SUCCEEDED(err))
pDisplayValuesIn = reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(new BYTE[dwItemCount*dwBufferSizeIn]);
@ -251,16 +276,24 @@ int check_network(vector <nInterface>& vInterfaces)
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Going over counter array" << endl;
for (DWORD i = 0; i < dwItemCount; i++) {
nInterface *iface = new nInterface(wstring(pDisplayValuesIn[i].szName));
iface->BytesInSec = pDisplayValuesIn[i].FmtValue.longValue;
iface->BytesOutSec = pDisplayValuesOut[i].FmtValue.longValue;
vInterfaces.push_back(*iface);
if (debug)
wcout << L"Collected interface " << pDisplayValuesIn[i].szName << endl;
}
PdhCloseQuery(phQuery);
delete pDisplayValuesIn;
delete pDisplayValuesOut;
return -1;
if (debug)
wcout << L"Finished collection. Cleaning up and returning" << endl;
PdhCloseQuery(phQuery);
delete reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(pDisplayValuesIn);
delete reinterpret_cast<PDH_FMT_COUNTERVALUE_ITEM*>(pDisplayValuesOut);
return -1;
die:
die(err);
if (phQuery)

View File

@ -40,6 +40,8 @@ namespace po = boost::program_options;
using std::cout; using std::endl; using std::wcout;
using std::wstring; using std::string;
static BOOL debug = FALSE;
struct response
{
double avg;
@ -97,6 +99,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print usage message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("host,H", po::wvalue<wstring>()->required(), "host ip to ping")
(",4", "--host is an ipv4 address (default)")
(",6", "--host is an ipv6 address")
@ -222,11 +225,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
printInfo.host = vm["host"].as<wstring>();
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(printInfoStruct& printInfo, response& response)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
double plp = ((double)response.dropped / printInfo.num) * 100.0;
@ -273,6 +282,9 @@ int check_ping4(const printInfoStruct& pi, response& response)
LARGE_INTEGER frequency, timer1, timer2;
LPCWSTR term;
if (debug)
wcout << L"Parsing ip address" << endl;
if (RtlIpv4StringToAddress(pi.host.c_str(), TRUE, &term, &ipDest4) == STATUS_INVALID_PARAMETER) {
std::wcout << pi.host << " is not a valid ip address" << std::endl;
return 3;
@ -283,6 +295,9 @@ int check_ping4(const printInfoStruct& pi, response& response)
return 3;
}
if (debug)
wcout << L"Creating Icmp File" << endl;
if ((hIcmp = IcmpCreateFile()) == INVALID_HANDLE_VALUE)
goto die;
@ -295,20 +310,33 @@ int check_ping4(const printInfoStruct& pi, response& response)
QueryPerformanceFrequency(&frequency);
do {
QueryPerformanceCounter(&timer1);
dwRet = IcmpSendEcho2(hIcmp, NULL, NULL, NULL, ipDest4.S_un.S_addr,
NULL, 0, NULL, repBuf, dwRepSize, pi.timeout);
if (!dwRet) {
if (debug)
wcout << L"Sending Icmp echo" << endl;
if (!IcmpSendEcho2(hIcmp, NULL, NULL, NULL, ipDest4.S_un.S_addr,
NULL, 0, NULL, repBuf, dwRepSize, pi.timeout)) {
response.dropped++;
if (debug)
wcout << L"Dropped: Response was 0" << endl;
continue;
}
if (debug)
wcout << "Ping recieved" << endl;
PICMP_ECHO_REPLY pEchoReply = static_cast<PICMP_ECHO_REPLY>(repBuf);
if (pEchoReply->Status != IP_SUCCESS) {
response.dropped++;
if (debug)
wcout << L"Dropped: echo reply status " << pEchoReply->Status << endl;
continue;
}
if (debug)
wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << endl;
rtt += pEchoReply->RoundTripTime;
if (response.pMin == 0 || pEchoReply->RoundTripTime < response.pMin)
response.pMin = pEchoReply->RoundTripTime;
@ -320,6 +348,8 @@ int check_ping4(const printInfoStruct& pi, response& response)
Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart));
} while (--num);
if (debug)
wcout << L"All pings sent. Cleaning up and returning" << endl;
IcmpCloseHandle(hIcmp);
delete reinterpret_cast<VOID *>(repBuf);
@ -350,6 +380,9 @@ int check_ping6(const printInfoStruct& pi, response& response)
int num = pi.num;
UINT rtt = 0;
if (debug)
wcout << L"Parsing ip address" << endl;
if (RtlIpv6StringToAddressEx(pi.host.c_str(), &ipDest6.sin6_addr, &ipDest6.sin6_scope_id, &ipDest6.sin6_port)) {
std::wcout << pi.host << " is not a valid ipv6 address" << std::endl;
return 3;
@ -362,6 +395,9 @@ int check_ping6(const printInfoStruct& pi, response& response)
ipSource6.sin6_flowinfo = 0;
ipSource6.sin6_port = 0;
if (debug)
wcout << L"Creating Icmp File" << endl;
HANDLE hIcmp = Icmp6CreateFile();
if (hIcmp == INVALID_HANDLE_VALUE) {
goto die;
@ -370,32 +406,50 @@ int check_ping6(const printInfoStruct& pi, response& response)
QueryPerformanceFrequency(&frequency);
do {
QueryPerformanceCounter(&timer1);
if (debug)
wcout << L"Sending Icmp echo" << endl;
if (!Icmp6SendEcho2(hIcmp, NULL, NULL, NULL, &ipSource6, &ipDest6,
NULL, 0, &ipInfo, repBuf, dwRepSize, pi.timeout)) {
response.dropped++;
if (debug)
wcout << L"Dropped: Response was 0" << endl;
continue;
}
if (debug)
wcout << "Ping recieved" << endl;
Icmp6ParseReplies(repBuf, dwRepSize);
ICMPV6_ECHO_REPLY *echoReply = static_cast<ICMPV6_ECHO_REPLY *>(repBuf);
ICMPV6_ECHO_REPLY *pEchoReply = static_cast<ICMPV6_ECHO_REPLY *>(repBuf);
if (echoReply->Status != IP_SUCCESS) {
if (pEchoReply->Status != IP_SUCCESS) {
response.dropped++;
if (debug)
wcout << L"Dropped: echo reply status " << pEchoReply->Status << endl;
continue;
}
rtt += echoReply->RoundTripTime;
if (response.pMin == 0 || echoReply->RoundTripTime < response.pMin)
response.pMin = echoReply->RoundTripTime;
else if (echoReply->RoundTripTime > response.pMax)
response.pMax = echoReply->RoundTripTime;
rtt += pEchoReply->RoundTripTime;
if (debug)
wcout << L"Recorded rtt of " << pEchoReply->RoundTripTime << endl;
if (response.pMin == 0 || pEchoReply->RoundTripTime < response.pMin)
response.pMin = pEchoReply->RoundTripTime;
else if (pEchoReply->RoundTripTime > response.pMax)
response.pMax = pEchoReply->RoundTripTime;
QueryPerformanceCounter(&timer2);
if (((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart) < pi.timeout)
Sleep(pi.timeout - ((timer2.QuadPart - timer1.QuadPart) * 1000 / frequency.QuadPart));
} while (--num);
if (debug)
wcout << L"All pings sent. Cleaning up and returning" << endl;
IcmpCloseHandle(hIcmp);
delete reinterpret_cast<VOID *>(repBuf);
response.avg = ((double)rtt / pi.num);

View File

@ -32,6 +32,8 @@ namespace po = boost::program_options;
using std::endl; using std::wstring; using std::wcout;
using std::cout;
static BOOL debug = FALSE;
struct printInfoStruct
{
threshold warn, crit;
@ -59,38 +61,6 @@ int wmain(int argc, wchar_t **argv)
return printOutput(countProcs(), printInfo);
}
int printOutput(const int numProcs, printInfoStruct& printInfo)
{
state state = OK;
if (printInfo.warn.rend(numProcs))
state = WARNING;
if (printInfo.crit.rend(numProcs))
state = CRITICAL;
wstring user = L"";
if (!printInfo.user.empty())
user.append(L" processes of user ").append(printInfo.user);
switch (state) {
case OK:
wcout << L"PROCS OK " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl;
break;
case WARNING:
wcout << L"PROCS WARNING " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl;
break;
case CRITICAL:
wcout << L"PROCS CRITICAL " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl;
break;
}
return state;
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
@ -102,9 +72,10 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print help message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("user,u", po::wvalue<wstring>(), "count only processes by user [arg]")
("warning,w", po::wvalue<wstring>(), "warning threshold")
("critical,c", po::wvalue<wstring>(), "critical threshold")
("user,u", po::wvalue<wstring>(), "count only processes by user [arg]")
;
po::basic_command_line_parser<wchar_t> parser(ac, av);
@ -132,7 +103,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << desc;
wprintf(
L"\nIt will then output a string looking something like this:\n\n"
L"\tPROCS WARNING 67|load=67;50;90;0\n\n"
L"\tPROCS WARNING 67 | load=67;50;90;0\n\n"
L"\"PROCS\" being the type of the check, \"WARNING\" the returned status\n"
L"and \"67\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
@ -191,20 +162,67 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
if (vm.count("user"))
printInfo.user = vm["user"].as<wstring>();
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(const int numProcs, printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
if (printInfo.warn.rend(numProcs))
state = WARNING;
if (printInfo.crit.rend(numProcs))
state = CRITICAL;
wstring user = L"";
if (!printInfo.user.empty())
user.append(L" processes of user ").append(printInfo.user);
switch (state) {
case OK:
wcout << L"PROCS OK " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl;
break;
case WARNING:
wcout << L"PROCS WARNING " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl;
break;
case CRITICAL:
wcout << L"PROCS CRITICAL " << numProcs << user << L" | procs=" << numProcs << L";"
<< printInfo.warn.pString() << L";" << printInfo.crit.pString() << L";0;" << endl;
break;
}
return state;
}
int countProcs()
{
if (debug)
wcout << L"Counting all processes" << endl;
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
if (debug)
wcout << L"Creating snapshot" << endl;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return -1;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (debug)
wcout << L"Grabbing first proccess" << endl;
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return -1;
@ -212,16 +230,25 @@ int countProcs()
int numProcs = 0;
if (debug)
wcout << L"Counting processes..." << endl;
do {
++numProcs;
} while (Process32Next(hProcessSnap, &pe32));
if (debug)
wcout << L"Found " << numProcs << L" processes. Cleaning up udn returning" << endl;
CloseHandle(hProcessSnap);
return numProcs;
}
int countProcs(const wstring user)
{
if (debug)
wcout << L"Counting all processes of user" << user << endl;
const wchar_t *wuser = user.c_str();
int numProcs = 0;
@ -232,16 +259,28 @@ int countProcs(const wstring user)
SID_NAME_USE sidNameUse;
LPWSTR AcctName, DomainName;
if (debug)
wcout << L"Creating snapshot" << endl;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
goto die;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (debug)
wcout << L"Grabbing first proccess" << endl;
if (!Process32First(hProcessSnap, &pe32))
goto die;
if (debug)
wcout << L"Counting processes..." << endl;
do {
if (debug)
wcout << L"Getting process token" << endl;
//get ProcessToken
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken))
@ -257,8 +296,14 @@ int countProcs(const wstring user)
pSIDTokenUser = reinterpret_cast<PTOKEN_USER>(new BYTE[dwReturnLength]);
memset(pSIDTokenUser, 0, dwReturnLength);
if (!pSIDTokenUser)
if (!pSIDTokenUser) {
if (debug)
wcout << L"Could not recieve token, skiping" << endl;
continue;
}
if (debug)
wcout << L"Recieved token, saving information" << endl;
//write Info in pSIDTokenUser
if (!GetTokenInformation(hToken, TokenUser, pSIDTokenUser, dwReturnLength, NULL))
@ -268,6 +313,10 @@ int countProcs(const wstring user)
DomainName = NULL;
dwAcctName = 1;
dwDomainName = 1;
if (debug)
wcout << L"Looking up SID" << endl;
//get dwAcctName and dwDomainName size
if (!LookupAccountSid(NULL, pSIDTokenUser->User.Sid, AcctName,
(LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse)
@ -284,8 +333,13 @@ int countProcs(const wstring user)
(LPDWORD)&dwAcctName, DomainName, (LPDWORD)&dwDomainName, &sidNameUse))
continue;
if (!wcscmp(AcctName, wuser))
if (debug)
wcout << L"Comparing " << AcctName << L" to " << wuser << endl;
if (!wcscmp(AcctName, wuser)) {
++numProcs;
if (debug)
wcout << L"Is process of " << wuser << L" (" << numProcs << L")" << endl;
}
delete[] reinterpret_cast<LPWSTR>(AcctName);
delete[] reinterpret_cast<LPWSTR>(DomainName);

View File

@ -31,6 +31,8 @@ namespace po = boost::program_options;
using std::wcout; using std::endl;
using std::cout; using std::wstring;
static BOOL debug;
struct printInfoStruct
{
bool warn;
@ -69,6 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print help message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("service,s", po::wvalue<wstring>(), "service to check (required)")
("warn,w", "return warning (1) instead of critical (2),\n when service is not running")
;
@ -132,12 +135,18 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
printInfo.warn = true;
printInfo.service = vm["service"].as<wstring>();
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(const printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
wstring perf;
state state = OK;
@ -166,6 +175,9 @@ int printOutput(const printInfoStruct& printInfo)
int ServiceStatus(const printInfoStruct& printInfo)
{
if (debug)
wcout << L"Opening SC Manager" << endl;
SC_HANDLE service_api = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
if (service_api == NULL)
goto die;
@ -174,6 +186,9 @@ int ServiceStatus(const printInfoStruct& printInfo)
DWORD cbBufSize = 0;
DWORD pcbBytesNeeded = NULL, ServicesReturned = NULL, ResumeHandle = NULL;
if (debug)
wcout << L"Creating service info structure" << endl;
if (!EnumServicesStatusEx(service_api, SC_ENUM_PROCESS_INFO, SERVICE_WIN32, SERVICE_STATE_ALL,
lpServices, cbBufSize, &pcbBytesNeeded, &ServicesReturned, &ResumeHandle, NULL)
&& GetLastError() != ERROR_MORE_DATA)
@ -188,16 +203,24 @@ int ServiceStatus(const printInfoStruct& printInfo)
LPENUM_SERVICE_STATUS_PROCESS pInfo = (LPENUM_SERVICE_STATUS_PROCESS)lpServices;
if (debug)
wcout << L"Traversing services" << endl;
for (DWORD i = 0; i < ServicesReturned; i++) {
if (debug)
wcout << L"Comparing " << pInfo[i].lpServiceName << L" to " << printInfo.service << endl;
if (!wcscmp(printInfo.service.c_str(), pInfo[i].lpServiceName)) {
if (debug)
wcout << L"Service " << pInfo[i].lpServiceName << L" = " << printInfo.service << ". Returning" << endl;
int state = pInfo[i].ServiceStatusProcess.dwCurrentState;
delete lpServices;
return state;
}
}
return 0;
delete[] reinterpret_cast<LPBYTE>(lpServices);
return -1;
return 0;
die:
die();

View File

@ -31,6 +31,8 @@ namespace po = boost::program_options;
using std::endl; using std::wcout; using std::wstring;
using std::cout;
static BOOL debug = FALSE;
struct printInfoStruct
{
threshold warn, crit;
@ -68,6 +70,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print help message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("warning,w", po::wvalue<wstring>(), "warning threshold")
("critical,c", po::wvalue<wstring>(), "critical threshold")
;
@ -141,6 +144,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
return 3;
}
}
if (vm.count("critical")) {
try {
printInfo.crit = threshold(vm["critical"].as<wstring>());
@ -150,11 +154,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
}
}
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
if (printInfo.warn.rend(printInfo.swap))
@ -192,18 +202,30 @@ int check_swap(printInfoStruct& printInfo)
LPCWSTR path = L"\\Paging File(*)\\% Usage";
if (debug)
wcout << L"Opening querry handle" << endl;
err = PdhOpenQuery(NULL, NULL, &phQuery);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Adding counter" << endl;
err = PdhAddEnglishCounter(phQuery, path, NULL, &phCounter);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Collecting querry data" << endl;
err = PdhCollectQueryData(phQuery);
if (!SUCCEEDED(err))
goto die;
if (debug)
wcout << L"Formatting counter data" << endl;
err = PdhGetFormattedCounterValue(phCounter, PDH_FMT_DOUBLE, &CounterType, &DisplayValue);
if (SUCCEEDED(err)) {
printInfo.swap = DisplayValue.doubleValue;

View File

@ -35,6 +35,8 @@ namespace po = boost::program_options;
using std::wcout; using std::endl;
using std::wstring; using std::cout;
static BOOL debug = FALSE;
struct printInfoStruct
{
BOOL warn, crit;
@ -46,10 +48,10 @@ static int parseArguments(int, wchar_t **, po::variables_map&, printInfoStruct&)
static int printOutput(const printInfoStruct&);
static int check_update(printInfoStruct&);
int main(int argc, wchar_t **argv)
int wmain(int argc, wchar_t **argv)
{
po::variables_map vm;
printInfoStruct printInfo = { FALSE, FALSE, 0, FALSE, FALSE, FALSE };
po::variables_map vm;
int ret = parseArguments(argc, argv, vm, printInfo);
if (ret != -1)
@ -62,35 +64,6 @@ int main(int argc, wchar_t **argv)
return printOutput(printInfo);
}
int printOutput(const printInfoStruct& printInfo)
{
state state = OK;
wstring output = L"UPDATE ";
if (printInfo.important)
state = WARNING;
if (printInfo.reboot)
state = CRITICAL;
switch (state) {
case OK:
output.append(L"OK ");
break;
case WARNING:
output.append(L"WARNING ");
break;
case CRITICAL:
output.append(L"CRITICAL ");
break;
}
wcout << output << printInfo.numUpdates << L" | update=" << printInfo.numUpdates << L";"
<< printInfo.warn << L";" << printInfo.crit << L";0;" << endl;
return state;
}
int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct& printInfo)
{
wchar_t namePath[MAX_PATH];
@ -102,9 +75,10 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print help message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("warning,w", "warn if there are important updates available")
("critical,c", "critical if there are important updates that require a reboot")
("possible-reboot", "treat \"update may need to reboot\" as \"update needs to reboot\"")
("possible-reboot", "treat \"update may need reboot\" as \"update needs reboot\"")
;
po::basic_command_line_parser<wchar_t> parser(ac, av);
@ -132,7 +106,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << desc;
wprintf(
L"\nAfter some time, it will then output a string like this one:\n\n"
L"\tUPDATE WARNING 8|updates=8;1;1;0\n\n"
L"\tUPDATE WARNING 8 | updates=8;1;1;0\n\n"
L"\"UPDATE\" being the type of the check, \"WARNING\" the returned status\n"
L"and \"8\" is the number of important updates updates.\n"
L"The performance data is found behind the \"|\", in order:\n"
@ -170,18 +144,56 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
if (vm.count("possible-reboot"))
printInfo.careForCanRequest = TRUE;
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(const printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
wstring output = L"UPDATE ";
if (printInfo.important)
state = WARNING;
if (printInfo.reboot)
state = CRITICAL;
switch (state) {
case OK:
output.append(L"OK ");
break;
case WARNING:
output.append(L"WARNING ");
break;
case CRITICAL:
output.append(L"CRITICAL ");
break;
}
wcout << output << printInfo.numUpdates << L" | update=" << printInfo.numUpdates << L";"
<< printInfo.warn << L";" << printInfo.crit << L";0;" << endl;
return state;
}
int check_update(printInfoStruct& printInfo)
{
if (debug)
wcout << "Initializing COM library" << endl;
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
ISearchResult *pResult;
IUpdateSession *pSession;
IUpdateSearcher *pSearcher;
HRESULT err;
if (debug)
wcout << "Creating UpdateSession and UpdateSearcher" << endl;
CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&pSession);
pSession->CreateUpdateSearcher(&pSearcher);
@ -196,6 +208,9 @@ int check_update(printInfoStruct& printInfo)
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa386526%28v=vs.85%29.aspx
// http://msdn.microsoft.com/en-us/library/ff357803%28v=vs.85%29.aspx
if (debug)
wcout << L"Querrying updates from server" << endl;
err = pSearcher->Search(criteria, &pResult);
if (!SUCCEEDED(err))
goto die;
@ -212,30 +227,40 @@ int check_update(printInfoStruct& printInfo)
return -1;
printInfo.numUpdates = updateSize;
printInfo.important = printInfo.warn;
if (!printInfo.crit)
return -1;
// printInfo.important = printInfo.warn;
IInstallationBehavior *pIbehav;
InstallationRebootBehavior updateReboot;
for (LONG i = 0; i < updateSize; i++) {
pCollection->get_Item(i, &pUpdate);
if (debug) {
wcout << L"Checking reboot behaviour of update number " << i << endl;
}
pUpdate->get_InstallationBehavior(&pIbehav);
pIbehav->get_RebootBehavior(&updateReboot);
if (updateReboot == irbAlwaysRequiresReboot) {
printInfo.reboot = TRUE;
if (debug)
wcout << L"It requires reboot" << endl;
continue;
}
if (printInfo.careForCanRequest && updateReboot == irbCanRequestReboot)
if (debug)
wcout << L"It requires reboot" << endl;
printInfo.reboot = TRUE;
}
if (debug)
wcout << L"Cleaning up and returning" << endl;
SysFreeString(criteria);
CoUninitialize();
return 0;
die:
die(err);
CoUninitialize();
if (criteria)
SysFreeString(criteria);
return 3;

View File

@ -32,6 +32,8 @@ namespace po = boost::program_options;
using std::cout; using std::endl;
using std::wcout; using std::wstring;
static BOOL debug;
struct printInfoStruct
{
threshold warn, crit;
@ -70,6 +72,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
("help,h", "print help message and exit")
("version,V", "print version and exit")
("warning,w", po::wvalue<wstring>(), "warning threshold (Uses -unit)")
("debug,d", "Verbose/Debug output")
("critical,c", po::wvalue<wstring>(), "critical threshold (Uses -unit)")
("unit,u", po::wvalue<wstring>(), "desired unit of output\nh\t- hours\nm\t- minutes\ns\t- seconds (default)\nms\t- milliseconds")
;
@ -164,12 +167,18 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
} wcout << L"Unknown unit type " << vm["unit"].as<wstring>() << endl;
} else
printInfo.unit = TunitS;
if (vm.count("debug"))
debug = TRUE;
return -1;
}
static int printOutput(printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
if (printInfo.warn.rend(printInfo.time))
@ -200,8 +209,14 @@ static int printOutput(printInfoStruct& printInfo)
void getUptime(printInfoStruct& printInfo)
{
if (debug)
wcout << L"Getting uptime in milliseconds" << endl;
boost::chrono::milliseconds uptime = boost::chrono::milliseconds(GetTickCount64());
if (debug)
wcout << L"Converting requested unit (default: seconds)" << endl;
switch (printInfo.unit) {
case TunitH:
printInfo.time = boost::chrono::duration_cast<boost::chrono::hours>(uptime).count();
@ -216,5 +231,4 @@ void getUptime(printInfoStruct& printInfo)
printInfo.time = uptime.count();
break;
}
}

View File

@ -32,6 +32,8 @@ namespace po = boost::program_options;
using std::endl; using std::wcout;
using std::cout; using std::wstring;
static BOOL debug = FALSE;
struct printInfoStruct
{
threshold warn, crit;
@ -69,6 +71,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
desc.add_options()
("help,h", "print help message and exit")
("version,V", "print version and exit")
("debug,d", "Verbose/Debug output")
("warning,w", po::wvalue<wstring>(), "warning threshold")
("critical,c", po::wvalue<wstring>(), "critical threshold")
;
@ -98,7 +101,7 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
cout << desc;
wprintf(
L"\nIt will then output a string looking something like this:\n\n"
L"\tUSERS WARNING 48|users=48;10;50;0\n\n"
L"\tUSERS WARNING 48 | users=48;10;50;0\n\n"
L"\"USERS\" being the type of the check, \"WARNING\" the returned status\n"
L"and \"48\" is the returned value.\n"
L"The performance data is found behind the \"|\", in order:\n"
@ -151,11 +154,17 @@ int parseArguments(int ac, wchar_t **av, po::variables_map& vm, printInfoStruct&
}
}
if (vm.count("debug"))
debug = TRUE;
return -1;
}
int printOutput(printInfoStruct& printInfo)
{
if (debug)
wcout << L"Constructing output string" << endl;
state state = OK;
if (printInfo.warn.rend(printInfo.users))
@ -189,33 +198,52 @@ int check_users(printInfoStruct& printInfo)
DWORD count;
DWORD index;
if (debug)
wcout << L"Trying to enumerate terminal sessions" << endl;
if (!WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &count)) {
wcout << L"Failed to enumerate terminal sessions" << endl;
die();
if (pSessionInfo)
WTSFreeMemory(pSessionInfo);
return 3;
}
if (debug)
wcout << L"Got all sessions (" << count << L"), traversing and counting active ones" << endl;
for (index = 0; index < count; index++) {
LPWSTR name;
DWORD size;
int len;
if (debug)
wcout << L"Querrying session number " << index << endl;
if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, pSessionInfo[index].SessionId,
WTSUserName, &name, &size))
continue;
if (debug)
wcout << L"Found \"" << name << L"\". Checking whether it's a real session" << endl;
len = lstrlenW(name);
WTSFreeMemory(name);
if (!len)
continue;
if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected)
if (pSessionInfo[index].State == WTSActive || pSessionInfo[index].State == WTSDisconnected) {
users++;
if (debug)
wcout << L"\"" << name << L"\" is a real session, counting it. Now " << users << endl;
}
}
if (debug)
wcout << "Finished coutning user sessions (" << users << "). Freeing memory and returning" << endl;
WTSFreeMemory(pSessionInfo);
printInfo.users = users;
return -1;