mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-06 00:13:33 +00:00
591 lines
18 KiB
C
591 lines
18 KiB
C
/*
|
|
Copyright 2006 - 2017 Intel Corporation
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(_MINCORE)
|
|
#define _CRTDBG_MAP_ALLOC
|
|
#include <crtdbg.h>
|
|
#endif
|
|
|
|
#if defined(WINSOCK2)
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <winsock2.h>
|
|
#include <ws2tcpip.h>
|
|
#include <iphlpapi.h>
|
|
#elif defined(WINSOCK1)
|
|
#include <winsock.h>
|
|
#include <wininet.h>
|
|
#elif defined(_POSIX)
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include <sys/socket.h>
|
|
#include <sys/types.h>
|
|
#include <net/if.h>
|
|
|
|
#include <sys/ioctl.h>
|
|
#include <net/if_arp.h>
|
|
#include <arpa/inet.h>
|
|
#include <sys/syscall.h>
|
|
#include <linux/reboot.h>
|
|
|
|
|
|
#define inaddrr(x) (*(struct in_addr *) &ifr->x[sizeof sa.sin_port])
|
|
#define IFRSIZE ((int)(size * sizeof (struct ifreq)))
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "../microstack/ILibParsers.h"
|
|
#include "../microstack/ILibCrypto.h"
|
|
#include "meshinfo.h"
|
|
|
|
|
|
#ifdef WINSOCK2
|
|
// This is the Windows implementation of a method that gets information about local interfaces
|
|
int info_GetLocalInterfaces(char* data, int maxdata)
|
|
{
|
|
#ifdef _MINCORE
|
|
return 0;
|
|
#else
|
|
IP_ADAPTER_INFO *pAdapterInfo;
|
|
IP_ADAPTER_ADDRESSES *pAdapterAddresses;
|
|
PIP_ADAPTER_INFO pAdapter;
|
|
PIP_ADAPTER_ADDRESSES pAdapterAddr;
|
|
ULONG ulOutBufLen = 0;
|
|
DWORD dwRetVal;
|
|
unsigned int j;
|
|
int adapterCount = 0;
|
|
unsigned long palen;
|
|
unsigned char pa[16];
|
|
int ptr = 0;
|
|
size_t templen;
|
|
char temp[1024];
|
|
IPAddr ip1;
|
|
IPAddr ip2;
|
|
|
|
// Lets see how much memory we need to get the list of local interfaces
|
|
pAdapterInfo = (IP_ADAPTER_INFO *)malloc(sizeof(IP_ADAPTER_INFO));
|
|
if (pAdapterInfo == NULL) return 0;
|
|
ulOutBufLen = sizeof(IP_ADAPTER_INFO);
|
|
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS) { free(pAdapterInfo); if (ulOutBufLen == 0) return 0; pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); }
|
|
|
|
// Get the list of all local interfaces
|
|
if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS || ulOutBufLen == 0) { free(pAdapterInfo); return 0; }
|
|
|
|
// Count how many interfaces are present
|
|
pAdapter = pAdapterInfo;
|
|
while (pAdapter) { adapterCount++; pAdapter = pAdapter->Next; }
|
|
|
|
// Lets see how much memory we need to get the list of local adapters
|
|
pAdapterAddresses = (IP_ADAPTER_ADDRESSES *)malloc(sizeof(IP_ADAPTER_ADDRESSES));
|
|
if (pAdapterAddresses == NULL) { free(pAdapterInfo); return 0; }
|
|
ulOutBufLen = sizeof(IP_ADAPTER_ADDRESSES);
|
|
if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddresses, &ulOutBufLen) != ERROR_SUCCESS)
|
|
{
|
|
free(pAdapterAddresses);
|
|
if (ulOutBufLen == 0) return 0;
|
|
pAdapterAddresses = (IP_ADAPTER_ADDRESSES *)malloc(ulOutBufLen);
|
|
}
|
|
|
|
// Get the list of all local interfaces
|
|
if ((dwRetVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_PREFIX, NULL, pAdapterAddresses, &ulOutBufLen)) != ERROR_SUCCESS || ulOutBufLen == 0) { free(pAdapterInfo); free(pAdapterAddresses); return 0; }
|
|
|
|
j = 0;
|
|
pAdapter = pAdapterInfo;
|
|
while (pAdapter)
|
|
{
|
|
// Find the corresponding adapter for this interface
|
|
pAdapterAddr = pAdapterAddresses;
|
|
while (pAdapterAddr != NULL && pAdapterAddr->IfIndex != pAdapter->Index) { pAdapterAddr = pAdapterAddr->Next; }
|
|
if (pAdapterAddr == NULL) { free(pAdapterInfo); free(pAdapterAddresses); return 0; }
|
|
|
|
if (j > 0) { ptr += snprintf(data + ptr, maxdata - ptr, ","); }
|
|
ptr += snprintf(data + ptr, maxdata - ptr, "{");
|
|
|
|
// Interface type
|
|
ptr += snprintf(data + ptr, maxdata - ptr, "\"type\":%d", pAdapter->Type);
|
|
|
|
// Interface name
|
|
if (wcslen(pAdapterAddr->FriendlyName) > 0) {
|
|
wcstombs_s(&templen, temp, 1023, pAdapterAddr->FriendlyName, wcslen(pAdapterAddr->FriendlyName));
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"name\":\"%s\"", temp);
|
|
}
|
|
|
|
// Interface description
|
|
if (wcslen(pAdapterAddr->Description) > 0) {
|
|
wcstombs_s(&templen, temp, 1023, pAdapterAddr->Description, wcslen(pAdapterAddr->Description));
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"desc\":\"%s\"", temp);
|
|
}
|
|
|
|
// Interface MAC address
|
|
if (pAdapter->AddressLength == 6) {
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"mac\":\"%02x%02x%02x%02x%02x%02x\"", pAdapter->Address[0], pAdapter->Address[1], pAdapter->Address[2], pAdapter->Address[3], pAdapter->Address[4], pAdapter->Address[5]);
|
|
}
|
|
|
|
// Interface DNS suffix
|
|
if (wcslen(pAdapterAddr->DnsSuffix) > 0) {
|
|
wcstombs_s(&templen, temp, 1023, pAdapterAddr->DnsSuffix, wcslen(pAdapterAddr->DnsSuffix));
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"dnssuffix\":\"%s\"", temp);
|
|
}
|
|
|
|
// IPv4 address and subnet mask
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"v4addr\":\"%s\"", pAdapter->IpAddressList.IpAddress.String);
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"v4mask\":\"%s\"", pAdapter->IpAddressList.IpMask.String);
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"v4gateway\":\"%s\"", pAdapter->GatewayList.IpAddress.String);
|
|
|
|
// Get the gateway MAC address
|
|
ILibInet_pton(AF_INET, pAdapter->IpAddressList.IpAddress.String, &ip1);
|
|
ILibInet_pton(AF_INET, pAdapter->GatewayList.IpAddress.String, &ip2);
|
|
SendARP(ip2, ip1, pa, &palen);
|
|
if (palen == 6) { ptr += snprintf(data + ptr, maxdata - ptr, ",\"gatewaymac\":\"%02x%02x%02x%02x%02x%02x\"", pa[0], pa[1], pa[2], pa[3], pa[4], pa[5]); }
|
|
|
|
ptr += snprintf(data + ptr, maxdata - ptr, "}");
|
|
|
|
j++;
|
|
pAdapter = pAdapter->Next;
|
|
}
|
|
|
|
// Free the local interface memory
|
|
free(pAdapterInfo);
|
|
free(pAdapterAddresses);
|
|
|
|
return ptr;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef _POSIX
|
|
|
|
// This method reads a stream where the length of the file can't be determined. Useful in POSIX only
|
|
int __fastcall utilx_readfile2(char* filename, char** data)
|
|
{
|
|
FILE * pFile;
|
|
int count = 0;
|
|
int len = 0;
|
|
*data = NULL;
|
|
if (filename == NULL) return 0;
|
|
|
|
pFile = fopen(filename, "rb");
|
|
if (pFile != NULL)
|
|
{
|
|
*data = malloc(1024);
|
|
if (*data == NULL) { fclose(pFile); return 0; }
|
|
do
|
|
{
|
|
len = fread((*data) + count, 1, 1023, pFile);
|
|
count += len;
|
|
if (len == 1023) *data = realloc(*data, count + 1024);
|
|
} while (len == 100);
|
|
(*data)[count] = 0;
|
|
fclose(pFile);
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
// TODO: Add support for IPv6, and check that it's on the correct interface
|
|
int info_GetHwAddress(char* ipaddr, int ipaddrlen, char** hwaddr)
|
|
{
|
|
char* arpcache = NULL;
|
|
int len, r = 0;
|
|
char* ptr = NULL;
|
|
char substr[32];
|
|
|
|
*hwaddr = NULL;
|
|
if (ipaddrlen >= 30 || (ipaddrlen == 7 && memcmp(ipaddr, "0.0.0.0", 7) == 0)) return 0;
|
|
len = utilx_readfile2("/proc/net/arp", &arpcache);
|
|
if (len == 0) return 0;
|
|
|
|
substr[0] = '\n';
|
|
memcpy(substr + 1, ipaddr, ipaddrlen);
|
|
substr[ipaddrlen + 1] = ' ';
|
|
substr[ipaddrlen + 2] = 0;
|
|
|
|
ptr = strstr(arpcache, substr);
|
|
if ((ptr != NULL) && (ptr + 61 < arpcache + len) && (ptr[44] == ':') && (ptr[47] == ':') && (ptr[56] == ':'))
|
|
{
|
|
if ((*hwaddr = (char*)malloc(6)) == NULL) ILIBCRITICALEXIT(254);
|
|
for (; r < 6; r++) { (*hwaddr)[r] = util_hexToint(ptr + 42 + (r * 3), 2); }
|
|
}
|
|
free(arpcache);
|
|
return r;
|
|
}
|
|
|
|
// The Linux equal of Windows SendARP
|
|
int SendARP(char* DestIP, char* SrcIP, void* pMacAddr, int* PhyAddrLen)
|
|
{
|
|
char tmp[50];
|
|
char* ptr = NULL;
|
|
ILibInet_ntop(AF_INET, DestIP, tmp, 50);
|
|
if (*PhyAddrLen < 6) return -1;
|
|
*PhyAddrLen = info_GetHwAddress(tmp, strlen(tmp), &ptr);
|
|
if (ptr != NULL)
|
|
{
|
|
memcpy(pMacAddr, ptr, 6);
|
|
free(ptr);
|
|
return 0;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// TODO: See if we can do this for each interface, right now interface is ignored
|
|
int info_GetDefaultFqdn(char* ifname, char** fqdn)
|
|
{
|
|
char* resolv;
|
|
int len, r = 0;
|
|
struct parser_result* parse;
|
|
struct parser_result_field* p;
|
|
struct parser_result* parse2;
|
|
struct parser_result_field* p2;
|
|
|
|
*fqdn = NULL;
|
|
len = utilx_readfile2("/etc/resolv.conf", &resolv);
|
|
if (len == 0) return 0;
|
|
|
|
parse = ILibParseString(resolv, 0, len, "\n", 1);
|
|
p = parse->FirstResult;
|
|
while (p != NULL)
|
|
{
|
|
parse2 = ILibParseString(p->data, 0, p->datalength, " ", 1);
|
|
p2 = parse2->FirstResult;
|
|
if (p2->datalength == 6 && memcmp(p2->data, "domain", 6) == 0)
|
|
{
|
|
// We found the system's default FQDN
|
|
r = p2->NextResult->datalength;
|
|
*fqdn = malloc(r + 1);
|
|
memcpy(*fqdn, p2->NextResult->data, r);
|
|
(*fqdn)[r] = 0;
|
|
ILibDestructParserResults(parse2);
|
|
break;
|
|
}
|
|
ILibDestructParserResults(parse2);
|
|
p = p->NextResult; // Skip to next line
|
|
}
|
|
ILibDestructParserResults(parse);
|
|
free(resolv);
|
|
return r;
|
|
}
|
|
|
|
// TODO: Add IPv6 support
|
|
int info_GetDefaultGateway(char* ifname, char** gateway)
|
|
{
|
|
char* route;
|
|
char* temp;
|
|
int len, r = 0, i;
|
|
int ifnamelen = strlen(ifname);
|
|
struct parser_result* parse;
|
|
struct parser_result_field* p;
|
|
struct parser_result* parse2;
|
|
struct parser_result_field* p2;
|
|
|
|
*gateway = NULL;
|
|
len = utilx_readfile2("/proc/net/route", &route);
|
|
if (len == 0) return 0;
|
|
|
|
parse = ILibParseString(route, 0, len, "\n", 1);
|
|
p = parse->FirstResult;
|
|
p = p->NextResult; // Skip the first line
|
|
while (p != NULL)
|
|
{
|
|
parse2 = ILibParseString(p->data, 0, p->datalength, "\t", 1);
|
|
p2 = parse2->FirstResult;
|
|
if (ifnamelen == p2->datalength && memcmp(p2->data, ifname, ifnamelen) == 0)
|
|
{
|
|
if (p2->NextResult->datalength == 8 && memcmp(p2->NextResult->data, "00000000", 8) == 0)
|
|
{
|
|
// We found the default gateway for this interface
|
|
r = p2->NextResult->NextResult->datalength / 2;
|
|
*gateway = malloc(r);
|
|
temp = p2->NextResult->NextResult->data;
|
|
for (i = 0; i < r; i++) { (*gateway)[r - (i + 1)] = util_hexToint(temp + (i * 2), 2); }
|
|
ILibDestructParserResults(parse2);
|
|
break;
|
|
}
|
|
}
|
|
ILibDestructParserResults(parse2);
|
|
p = p->NextResult; // Skip to next line
|
|
}
|
|
ILibDestructParserResults(parse);
|
|
free(route);
|
|
return r;
|
|
}
|
|
|
|
// This is the POSIX implementation of a method that gets information about local interfaces
|
|
int info_GetLocalInterfaces(char* data, int maxdata)
|
|
{
|
|
#ifdef NACL
|
|
return 0;
|
|
#else
|
|
|
|
int ptr = 0;
|
|
int sockfd, size = 1, j;
|
|
int adapterCount = 0;
|
|
struct ifreq *ifr;
|
|
struct ifconf ifc;
|
|
char temp[1024];
|
|
char* gateway = NULL;
|
|
|
|
// Fetch the list of local interfaces
|
|
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) return 0;
|
|
ifc.ifc_len = IFRSIZE;
|
|
ifc.ifc_req = NULL;
|
|
do
|
|
{
|
|
++size;
|
|
// realloc buffer size until no overflow occurs
|
|
if ((ifc.ifc_req = realloc(ifc.ifc_req, IFRSIZE)) == NULL) return 0;
|
|
ifc.ifc_len = IFRSIZE;
|
|
if (ioctl(sockfd, SIOCGIFCONF, &ifc) != 0) return 0;
|
|
} while (IFRSIZE <= ifc.ifc_len);
|
|
|
|
ifr = ifc.ifc_req;
|
|
for (; (char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len; ++ifr)
|
|
{
|
|
if (ifr->ifr_addr.sa_data == (ifr + 1)->ifr_addr.sa_data) continue; // Duplicate
|
|
if (ioctl(sockfd, SIOCGIFFLAGS, ifr)) continue; // Failed
|
|
if (memcmp(ifr->ifr_name, "lo", 3) == 0) continue; // Loopback
|
|
|
|
if (adapterCount > 0) { ptr += snprintf(data + ptr, maxdata - ptr, ","); }
|
|
ptr += snprintf(data + ptr, maxdata - ptr, "{");
|
|
|
|
// Get the name of the interface
|
|
ptr += snprintf(data + ptr, maxdata - ptr, "\"name\":\"%s\"", ifr->ifr_name);
|
|
|
|
// Get the FQDN (DNS Suffix)
|
|
j = info_GetDefaultFqdn(ifr->ifr_name, &gateway);
|
|
if (j > 0) { ptr += snprintf(data + ptr, maxdata - ptr, ",\"dnssuffix\":\"%s\"", gateway); }
|
|
if (gateway != NULL) { free(gateway); gateway = NULL; }
|
|
|
|
// Get the Default Gateway IP address
|
|
j = info_GetDefaultGateway(ifr->ifr_name, &gateway);
|
|
if (j == 4) { ILibInet_ntop(AF_INET, gateway, temp, 1024); ptr += snprintf(data + ptr, maxdata - ptr, ",\"v4gateway\":\"%s\"", temp); }
|
|
if (gateway != NULL) { free(gateway); gateway = NULL; }
|
|
|
|
// Get the Default Gateway MAC address
|
|
j = info_GetHwAddress(temp, strlen(temp), &gateway);
|
|
if (j == 6) { ptr += snprintf(data + ptr, maxdata - ptr, ",\"gatewaymac\":\"%02x%02x%02x%02x%02x%02x\"", (unsigned char)gateway[0], (unsigned char)gateway[1], (unsigned char)gateway[2], (unsigned char)gateway[3], (unsigned char)gateway[4], (unsigned char)gateway[5]); }
|
|
if (gateway != NULL) free(gateway);
|
|
|
|
// Attempt to figure out the interface type
|
|
j = 0;
|
|
if (strlen(ifr->ifr_name) > 3 && memcmp(ifr->ifr_name, "eth", 3) == 0) { j = 6; }
|
|
//if (strlen(ifr->ifr_name) > 2 && memcmp(ifr->ifr_name, "wl", 2) == 0) { j = 6; } // TODO: Wireless
|
|
if (j > 0) { ptr += snprintf(data + ptr, maxdata - ptr, ",\"type\":\"%d\"", j); }
|
|
|
|
// Get the hardware MAC address
|
|
if (ioctl(sockfd, SIOCGIFHWADDR, ifr) == 0) {
|
|
if (ifr->ifr_hwaddr.sa_family == 1) {
|
|
ptr += snprintf(data + ptr, maxdata - ptr, ",\"mac\":\"%02x%02x%02x%02x%02x%02x\"", (unsigned char)ifr->ifr_hwaddr.sa_data[0], (unsigned char)ifr->ifr_hwaddr.sa_data[1], (unsigned char)ifr->ifr_hwaddr.sa_data[2], (unsigned char)ifr->ifr_hwaddr.sa_data[3], (unsigned char)ifr->ifr_hwaddr.sa_data[4], (unsigned char)ifr->ifr_hwaddr.sa_data[5]);
|
|
}
|
|
}
|
|
|
|
// Get the IP address
|
|
if (ioctl(sockfd, SIOCGIFADDR, ifr) == 0) { ptr += snprintf(data + ptr, maxdata - ptr, ",\"v4addr\":\"%s\"", inet_ntoa(((struct sockaddr_in*)(&(ifr->ifr_addr)))->sin_addr)); }
|
|
|
|
// Get the subnet mask
|
|
if (ioctl(sockfd, SIOCGIFNETMASK, ifr) == 0) { ptr += snprintf(data + ptr, maxdata - ptr, ",\"v4mask\":\"%s\"", inet_ntoa(((struct sockaddr_in*)(&(ifr->ifr_addr)))->sin_addr)); }
|
|
|
|
ptr += snprintf(data + ptr, maxdata - ptr, "}");
|
|
adapterCount++;
|
|
}
|
|
|
|
free(ifc.ifc_req);
|
|
close(sockfd);
|
|
return ptr;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
// Returns a JSON text with system information
|
|
int MeshInfo_GetSystemInformation(char** data)
|
|
{
|
|
int ptr = 0;
|
|
|
|
// Setup the response
|
|
*data = (char*)malloc(65536);
|
|
ptr += snprintf(*data + ptr, 65536 - ptr, "{\"netif\":[");
|
|
ptr += info_GetLocalInterfaces(*data + ptr, 65536 - ptr);
|
|
ptr += snprintf(*data + ptr, 65536 - ptr, "]}");
|
|
(*data)[ptr] = 0;
|
|
*data = realloc(*data, ptr + 1);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
|
|
#ifdef WIN32
|
|
#if defined(_LINKVM)
|
|
DWORD WINAPI kvm_ctrlaltdel(LPVOID Param);
|
|
#endif
|
|
|
|
int MeshInfo_PowerState(enum AgentPowerStateActions flg, int force)
|
|
{
|
|
#ifdef _MINCORE
|
|
if (flg == 0 || flg > 5) return 0; // NOP
|
|
switch (flg)
|
|
{
|
|
case POWERSTATE_SHUTDOWN: // SHUTDOWN
|
|
InitiateSystemShutdownEx(NULL, NULL, 30, TRUE, FALSE, SHTDN_REASON_MINOR_OTHER);
|
|
break;
|
|
case POWERSTATE_REBOOT: // REBOOT
|
|
InitiateSystemShutdownEx(NULL, NULL, 30, TRUE, TRUE, SHTDN_REASON_MINOR_OTHER);
|
|
break;
|
|
}
|
|
return 1;
|
|
#else
|
|
TOKEN_PRIVILEGES tp;
|
|
BOOL fResult = 0;
|
|
HANDLE ht;
|
|
|
|
if (flg == POWERSTATE_NOP) return 0; // NOP
|
|
if (flg == POWERSTATE_DISPLAYON) { SetThreadExecutionState(ES_DISPLAY_REQUIRED); SetThreadExecutionState(ES_USER_PRESENT); return 1; } // Turn on display
|
|
if (flg == POWERSTATE_KEEPAWAKE) { SetThreadExecutionState(ES_SYSTEM_REQUIRED); return 1; } // Keep system awake
|
|
if (flg == POWERSTATE_BEEP) { MessageBeep(0xFFFFFFFF); return 1; }
|
|
if (flg == POWERSTATE_CTRLALTDEL)
|
|
{
|
|
#if defined(_LINKVM)
|
|
ht = CreateThread(NULL, 0, kvm_ctrlaltdel, 0, 0, 0);
|
|
if (ht != NULL) CloseHandle(ht);
|
|
return 1;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
// Attempt to exit
|
|
if (flg > POWERSTATE_HIBERNATE) return 0; // NOP
|
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &ht)) return 0;
|
|
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tp.Privileges[0].Luid);
|
|
tp.PrivilegeCount = 1;
|
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
AdjustTokenPrivileges(ht, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
|
if (GetLastError() != ERROR_SUCCESS) { CloseHandle(ht); return 0; }
|
|
|
|
switch (flg)
|
|
{
|
|
case POWERSTATE_LOGOFF: // LOGOFF
|
|
if (force) fResult = ExitWindowsEx(EWX_LOGOFF | EWX_FORCE, SHTDN_REASON_FLAG_PLANNED);
|
|
else fResult = ExitWindowsEx(EWX_LOGOFF, SHTDN_REASON_FLAG_PLANNED);
|
|
break;
|
|
case POWERSTATE_SHUTDOWN: // SHUTDOWN
|
|
fResult = InitiateSystemShutdown(NULL, NULL, 30, TRUE, FALSE);
|
|
break;
|
|
case POWERSTATE_REBOOT: // REBOOT
|
|
fResult = InitiateSystemShutdown(NULL, NULL, 30, TRUE, TRUE);
|
|
break;
|
|
case POWERSTATE_SLEEP: // SLEEP
|
|
fResult = SetSystemPowerState(TRUE, force);
|
|
break;
|
|
case POWERSTATE_HIBERNATE: // HIBERNATE
|
|
fResult = SetSystemPowerState(FALSE, force);
|
|
break;
|
|
}
|
|
|
|
if (!fResult) { CloseHandle(ht); return 0; }
|
|
tp.Privileges[0].Attributes = 0;
|
|
AdjustTokenPrivileges(ht, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
|
|
CloseHandle(ht);
|
|
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
#elif _VX_CPU // If VxWorks, we still need to implement this.
|
|
|
|
int MeshInfo_PowerState(enum AgentPowerStateActions flg, int force)
|
|
{
|
|
// TODO
|
|
return 0;
|
|
}
|
|
|
|
#else
|
|
|
|
int MeshInfo_PowerState(enum AgentPowerStateActions flg, int force)
|
|
{
|
|
switch (flg)
|
|
{
|
|
case POWERSTATE_NOP:
|
|
case POWERSTATE_DISPLAYON:
|
|
case POWERSTATE_KEEPAWAKE:
|
|
case POWERSTATE_BEEP:
|
|
case POWERSTATE_CTRLALTDEL:
|
|
// NO OP
|
|
break;
|
|
case POWERSTATE_LOGOFF: // LOGOFF
|
|
break;
|
|
case POWERSTATE_SHUTDOWN: // SHUTDOWN
|
|
#if defined(_ANDROID)
|
|
reboot(RB_POWER_OFF);
|
|
#elif defined(__APPLE__)
|
|
// TODO
|
|
#elif defined(NACL)
|
|
//do nothing
|
|
#else
|
|
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF, 0);
|
|
#endif
|
|
return 1;
|
|
case POWERSTATE_REBOOT: // REBOOT
|
|
#if defined(_ANDROID) || defined(__APPLE__)
|
|
reboot(RB_AUTOBOOT);
|
|
#elif defined(NACL)
|
|
//do nothing
|
|
#else
|
|
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART, 0);
|
|
#endif
|
|
return 1;
|
|
case POWERSTATE_SLEEP: // SLEEP
|
|
#if defined(__APPLE__)
|
|
{
|
|
io_connect_t port = IOPMFindPowerManagement(MACH_PORT_NULL);
|
|
IOPMSleepSystem(port);
|
|
IOServiceClose(port);
|
|
}
|
|
#endif
|
|
break;
|
|
#ifdef LINUX_REBOOT_CMD_SW_SUSPEND
|
|
case POWERSTATE_HIBERNATE: // HIBERNATE
|
|
#if defined(_ANDROID) || defined(__APPLE__)
|
|
// TODO
|
|
#else
|
|
syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_SW_SUSPEND, 0);
|
|
#endif
|
|
return 1;
|
|
#endif
|
|
case POWERSTATE_VIBRATE: // VIBRATE
|
|
#if defined(ANDROID)
|
|
{
|
|
ai_vibrate(1000);
|
|
}
|
|
#endif
|
|
break;
|
|
case POWERSTATE_FLASH: // FLASH
|
|
#if defined(ANDROID)
|
|
{
|
|
ai_flash(1000);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|