mirror of
https://github.com/Wind4/vlmcsd.git
synced 2025-06-23 15:54:33 +02:00
vlmcsd-1113-2020-03-28-Hotbird64
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
#include "endian.h"
|
||||
|
||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
|
||||
&& defined(BS16) && defined(BS32) && defined(BS64)
|
||||
&& defined(BS16) && defined(BS32) && defined(BS64) && !defined(NO_COMPILER_UAA)
|
||||
|
||||
#else // ! defined(__BYTE_ORDER)
|
||||
|
||||
@ -136,8 +136,12 @@ unsigned short GET_UAA16LE(void *p, unsigned int i)
|
||||
(unsigned short)_p[ 0 ] |
|
||||
(unsigned short)_p[ 1 ] << 8;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
|
||||
&& defined(BS16) && defined(BS32) && defined(BS64)
|
||||
#else
|
||||
unsigned short BE16(unsigned short x)
|
||||
{
|
||||
return GET_UAA16BE(&x, 0);
|
||||
|
88
src/endian.h
88
src/endian.h
@ -9,17 +9,17 @@
|
||||
//
|
||||
// Unaligned access
|
||||
//
|
||||
|
||||
#if !defined(NO_COMPILER_UAA)
|
||||
#define UAA16(p, i) (((PACKED16*)p)->val[i])
|
||||
#define UAA32(p, i) (((PACKED32*)p)->val[i])
|
||||
#define UAA64(p, i) (((PACKED64*)p)->val[i])
|
||||
|
||||
#define UA64(p) UAA64(p, 0)
|
||||
#define UA32(p) UAA32(p, 0)
|
||||
#define UA16(p) UAA16(p, 0)
|
||||
#endif
|
||||
|
||||
//
|
||||
//Byteswap: Use compiler support if available
|
||||
//
|
||||
#ifndef NO_COMPILER_UAA
|
||||
#ifdef __has_builtin // Clang supports this
|
||||
|
||||
#if __has_builtin(__builtin_bswap16)
|
||||
@ -56,6 +56,7 @@
|
||||
#endif // GNU C > 4.7
|
||||
#endif // __GNUC__ > 4
|
||||
#endif // __GNUC__
|
||||
#endif // NO_COMPILER_UAA
|
||||
|
||||
//
|
||||
// Byteorder
|
||||
@ -198,6 +199,10 @@
|
||||
#define __BE64(x) BS64(x)
|
||||
#define __LE64(x) (x)
|
||||
|
||||
#define PUT_UA16(p, v) PUT_UA16LE(p, v)
|
||||
#define PUT_UA32(p, v) PUT_UA32LE(p, v)
|
||||
#define PUT_UA64(p, v) PUT_UA64LE(p, v)
|
||||
|
||||
#else // __BYTE_ORDER == __BIG_ENDIAN
|
||||
|
||||
#define __BE16(x) (x)
|
||||
@ -207,8 +212,38 @@
|
||||
#define __BE64(x) (x)
|
||||
#define __LE64(x) BS64(x)
|
||||
|
||||
#define PUT_UA16(p, v) PUT_UA16BE(p, v)
|
||||
#define PUT_UA32(p, v) PUT_UA32BE(p, v)
|
||||
#define PUT_UA64(p, v) PUT_UA64BE(p, v)
|
||||
|
||||
#endif // __BYTE_ORDER
|
||||
|
||||
#define BE16(x) __BE16(x)
|
||||
#define LE16(x) __LE16(x)
|
||||
#define BE32(x) __BE32(x)
|
||||
#define LE32(x) __LE32(x)
|
||||
#define BE64(x) __BE64(x)
|
||||
#define LE64(x) __LE64(x)
|
||||
|
||||
#else
|
||||
|
||||
extern unsigned short BE16(unsigned short x);
|
||||
|
||||
extern unsigned short LE16(unsigned short x);
|
||||
|
||||
extern unsigned int BE32(unsigned int x);
|
||||
|
||||
extern unsigned int LE32(unsigned int x);
|
||||
|
||||
extern unsigned long long BE64(unsigned long long x);
|
||||
|
||||
extern unsigned long long LE64(unsigned long long x);
|
||||
|
||||
#endif // defined(__BYTE_ORDER)
|
||||
|
||||
#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) \
|
||||
&& defined(BS16) && defined(BS32) && defined(BS64) &&!defined(NO_COMPILER_UAA)
|
||||
|
||||
#define PUT_UAA64BE(p, v, i) ( UAA64(p, i) = __BE64(v) )
|
||||
#define PUT_UAA32BE(p, v, i) ( UAA32(p, i) = __BE32(v) )
|
||||
#define PUT_UAA16BE(p, v, i) ( UAA16(p, i) = __BE16(v) )
|
||||
@ -225,57 +260,38 @@
|
||||
#define GET_UAA32LE(p, i) __LE32(UAA32(p, i))
|
||||
#define GET_UAA16LE(p, i) __LE16(UAA16(p, i))
|
||||
|
||||
#define BE16(x) __BE16(x)
|
||||
#define LE16(x) __LE16(x)
|
||||
#define BE32(x) __BE32(x)
|
||||
#define LE32(x) __LE32(x)
|
||||
#define BE64(x) __BE64(x)
|
||||
#define LE64(x) __LE64(x)
|
||||
|
||||
#else // ! defined(__BYTE_ORDER)
|
||||
|
||||
extern void PUT_UAA64BE(void *p, unsigned long long v, unsigned int i);
|
||||
extern void PUT_UAA64BE(void* p, unsigned long long v, unsigned int i);
|
||||
|
||||
extern void PUT_UAA32BE(void *p, unsigned int v, unsigned int i);
|
||||
extern void PUT_UAA32BE(void* p, unsigned int v, unsigned int i);
|
||||
|
||||
extern void PUT_UAA16BE(void *p, unsigned short v, unsigned int i);
|
||||
extern void PUT_UAA16BE(void* p, unsigned short v, unsigned int i);
|
||||
|
||||
|
||||
extern void PUT_UAA64LE(void *p, unsigned long long v, unsigned int i);
|
||||
extern void PUT_UAA64LE(void* p, unsigned long long v, unsigned int i);
|
||||
|
||||
extern void PUT_UAA32LE(void *p, unsigned int v, unsigned int i);
|
||||
extern void PUT_UAA32LE(void* p, unsigned int v, unsigned int i);
|
||||
|
||||
extern void PUT_UAA16LE(void *p, unsigned short v, unsigned int i);
|
||||
extern void PUT_UAA16LE(void* p, unsigned short v, unsigned int i);
|
||||
|
||||
|
||||
extern unsigned long long GET_UAA64BE(void *p, unsigned int i);
|
||||
extern unsigned long long GET_UAA64BE(void* p, unsigned int i);
|
||||
|
||||
extern unsigned int GET_UAA32BE(void *p, unsigned int i);
|
||||
extern unsigned int GET_UAA32BE(void* p, unsigned int i);
|
||||
|
||||
extern unsigned short GET_UAA16BE(void *p, unsigned int i);
|
||||
extern unsigned short GET_UAA16BE(void* p, unsigned int i);
|
||||
|
||||
|
||||
extern unsigned long long GET_UAA64LE(void *p, unsigned int i);
|
||||
extern unsigned long long GET_UAA64LE(void* p, unsigned int i);
|
||||
|
||||
extern unsigned int GET_UAA32LE(void *p, unsigned int i);
|
||||
extern unsigned int GET_UAA32LE(void* p, unsigned int i);
|
||||
|
||||
extern unsigned short GET_UAA16LE(void *p, unsigned int i);
|
||||
extern unsigned short GET_UAA16LE(void* p, unsigned int i);
|
||||
#endif
|
||||
|
||||
|
||||
extern unsigned short BE16(unsigned short x);
|
||||
|
||||
extern unsigned short LE16(unsigned short x);
|
||||
|
||||
extern unsigned int BE32(unsigned int x);
|
||||
|
||||
extern unsigned int LE32(unsigned int x);
|
||||
|
||||
extern unsigned long long BE64(unsigned long long x);
|
||||
|
||||
extern unsigned long long LE64(unsigned long long x);
|
||||
|
||||
#endif // defined(__BYTE_ORDER)
|
||||
|
||||
|
||||
#define PUT_UA64BE(p, v) PUT_UAA64BE(p, v, 0)
|
||||
#define PUT_UA32BE(p, v) PUT_UAA32BE(p, v, 0)
|
||||
|
@ -434,14 +434,14 @@ __pure BOOL getArgumentBool(int_fast8_t *result, const char *const argument)
|
||||
#ifndef NO_EXTERNAL_DATA
|
||||
__noreturn static void dataFileReadError()
|
||||
{
|
||||
int error = errno;
|
||||
const int error = errno;
|
||||
errorout("Fatal: Could not read %s: %s\n", fn_data, strerror(error));
|
||||
exit(error);
|
||||
}
|
||||
|
||||
__noreturn static void dataFileFormatError()
|
||||
{
|
||||
errorout("Fatal: %s is not a KMS data file\n", fn_data);
|
||||
errorout("Fatal: %s is not a KMS data file version 2.x\n", fn_data);
|
||||
exit(VLMCSD_EINVAL);
|
||||
}
|
||||
#endif // NO_EXTERNAL_DATA
|
||||
@ -526,7 +526,7 @@ static void getDefaultDataFile()
|
||||
getExeName();
|
||||
strncpy(fileName, fn_exe, MAX_PATH);
|
||||
PathRemoveFileSpec(fileName);
|
||||
strncat(fileName, "\\vlmcsd.kmd", MAX_PATH);
|
||||
strncat(fileName, "\\vlmcsd.kmd", MAX_PATH - 11);
|
||||
fn_data = vlmcsd_strdup(fileName);
|
||||
}
|
||||
#else // !_WIN32
|
||||
@ -588,12 +588,12 @@ void loadKmsData()
|
||||
KmsData = (PVlmcsdHeader_t)vlmcsd_malloc(size);
|
||||
if (fseek(file, 0, SEEK_SET)) dataFileReadError();
|
||||
|
||||
size_t bytesRead = fread(KmsData, 1, size, file);
|
||||
const size_t bytesRead = fread(KmsData, 1, size, file);
|
||||
if ((long)bytesRead != size) dataFileReadError();
|
||||
fclose(file);
|
||||
|
||||
# if !defined(NO_LOG) && !defined(NO_SOCKETS)
|
||||
if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)KmsData->MajorVer, (unsigned int)KmsData->MinorVer, fn_data);
|
||||
if (!InetdMode) logger("Read KMS data file version %u.%u %s\n", (unsigned int)LE16(KmsData->MajorVer), (unsigned int)LE16(KmsData->MinorVer), fn_data);
|
||||
# endif // NO_LOG
|
||||
}
|
||||
}
|
||||
@ -610,6 +610,7 @@ void loadKmsData()
|
||||
KmsData->AppItemCount = LE32(KmsData->AppItemCount);
|
||||
KmsData->KmsItemCount = LE32(KmsData->KmsItemCount);
|
||||
KmsData->SkuItemCount = LE32(KmsData->SkuItemCount);
|
||||
KmsData->HostBuildCount = LE32(KmsData->HostBuildCount);
|
||||
|
||||
uint32_t i;
|
||||
|
||||
@ -625,6 +626,7 @@ void loadKmsData()
|
||||
{
|
||||
PCsvlkData_t csvlkData = &KmsData->CsvlkData[i];
|
||||
csvlkData->EPid = (char*)KmsData + LE64(csvlkData->EPidOffset);
|
||||
csvlkData->ReleaseDate = LE64(csvlkData->ReleaseDate);
|
||||
# ifndef UNSAFE_DATA_LOAD
|
||||
if (csvlkData->EPid > (char*)KmsData + size) dataFileFormatError();
|
||||
# endif // UNSAFE_DATA_LOAD
|
||||
@ -636,12 +638,25 @@ void loadKmsData()
|
||||
# endif // NO_RANDOM_EPID
|
||||
}
|
||||
|
||||
for (i = 0; i < (uint32_t)KmsData->HostBuildCount; i++)
|
||||
{
|
||||
PHostBuild_t hostBuild = &KmsData->HostBuildList[i];
|
||||
hostBuild->BuildNumber = LE32(hostBuild->BuildNumber);
|
||||
hostBuild->Flags = LE32(hostBuild->Flags);
|
||||
hostBuild->PlatformId = LE32(hostBuild->PlatformId);
|
||||
hostBuild->ReleaseDate = LE64(hostBuild->ReleaseDate);
|
||||
hostBuild->DisplayName = (char*)KmsData + LE64(hostBuild->DisplayNameOffset);
|
||||
# ifndef UNSAFE_DATA_LOAD
|
||||
if (hostBuild->DisplayName > (char*)KmsData + size) dataFileFormatError();
|
||||
# endif // UNSAFE_DATA_LOAD
|
||||
}
|
||||
|
||||
const uint32_t totalItemCount = KmsData->AppItemCount + KmsData->KmsItemCount + KmsData->SkuItemCount;
|
||||
|
||||
# ifndef NO_EXTERNAL_DATA
|
||||
if (
|
||||
memcmp(KmsData->Magic, "KMD", sizeof(KmsData->Magic)) ||
|
||||
KmsData->MajorVer != 1
|
||||
KmsData->MajorVer != 2
|
||||
# ifndef UNSAFE_DATA_LOAD
|
||||
||
|
||||
sizeof(VlmcsdHeader_t) + totalItemCount * sizeof(VlmcsdData_t) >= ((uint64_t)size)
|
||||
|
209
src/kms.c
209
src/kms.c
@ -57,16 +57,23 @@ int32_t getProductIndex(const GUID* guid, const PVlmcsdData_t list, const int32_
|
||||
}
|
||||
}
|
||||
|
||||
if (name) *name = "Unknown";
|
||||
if (ePid) *ePid = KmsData->CsvlkData[EPID_INDEX_WINDOWS].EPid;
|
||||
if (name) *name = (char*)"Unknown";
|
||||
if (ePid) *ePid = KmsData->CsvlkData->EPid;
|
||||
return i;
|
||||
}
|
||||
|
||||
#if !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
|
||||
const char* getNextString(const char* s)
|
||||
{
|
||||
return s + strlen(s) + 1;
|
||||
}
|
||||
#endif //!defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
|
||||
|
||||
#endif // IS_LIBRARY
|
||||
|
||||
|
||||
#ifndef NO_RANDOM_EPID
|
||||
static const uint16_t HostBuilds[] = { 6002, 7601, 9200, 9600, 14393, 17763 };
|
||||
//static const uint16_t HostBuilds[] = { 6002, 7601, 9200, 9600, 14393, 17763 };
|
||||
|
||||
// Valid language identifiers to be used in the ePID
|
||||
static const uint16_t LcidList[] = {
|
||||
@ -80,14 +87,38 @@ static const uint16_t LcidList[] = {
|
||||
17418, 18442, 19466, 20490, 1089, 1053, 2077, 1114, 1097, 1092, 1098, 1054, 1074, 1058, 1056, 1091, 2115, 1066, 1106, 1076, 1077
|
||||
};
|
||||
|
||||
uint16_t getPlatformId(uint16_t hostBuild)
|
||||
int32_t getPlatformId(int32_t hostBuild)
|
||||
{
|
||||
if (hostBuild < 9000) return 55041;
|
||||
if (hostBuild <= 9500) return 5426;
|
||||
if (hostBuild <= 10000) return 6401;
|
||||
return 3612;
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < KmsData->HostBuildCount; i++)
|
||||
{
|
||||
if (KmsData->HostBuildList[i].BuildNumber <= hostBuild)
|
||||
{
|
||||
return KmsData->HostBuildList[i].PlatformId;
|
||||
}
|
||||
}
|
||||
|
||||
return KmsData->HostBuildList[KmsData->HostBuildCount - 1].PlatformId;
|
||||
}
|
||||
|
||||
|
||||
time_t getReleaseDate(int32_t hostBuild)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = KmsData->HostBuildCount - 1; i >= 0; i--)
|
||||
{
|
||||
if (KmsData->HostBuildList[i].BuildNumber >= hostBuild)
|
||||
{
|
||||
return (time_t)KmsData->HostBuildList[i].ReleaseDate;
|
||||
}
|
||||
}
|
||||
|
||||
return (time_t)KmsData->HostBuildList->ReleaseDate;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _PEDANTIC
|
||||
uint16_t IsValidLcid(const uint16_t lcid)
|
||||
{
|
||||
@ -102,13 +133,13 @@ uint16_t IsValidLcid(const uint16_t lcid)
|
||||
}
|
||||
|
||||
|
||||
uint16_t IsValidHostBuild(const uint16_t hostBuild)
|
||||
uint32_t IsValidHostBuild(const int32_t hostBuild)
|
||||
{
|
||||
const uint16_t *hostOS;
|
||||
PHostBuild_t hostOS;
|
||||
|
||||
for (hostOS = HostBuilds; hostOS < HostBuilds + vlmcsd_countof(HostBuilds); hostOS++)
|
||||
for (hostOS = KmsData->HostBuildList; hostOS < KmsData->HostBuildList + KmsData->HostBuildCount; hostOS++)
|
||||
{
|
||||
if (hostBuild == *hostOS) return hostBuild;
|
||||
if (hostBuild == hostOS->BuildNumber) return hostBuild;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -119,7 +150,7 @@ uint16_t IsValidHostBuild(const uint16_t hostBuild)
|
||||
|
||||
// Unix time is seconds from 1970-01-01. Should be 64 bits to avoid year 2038 overflow bug.
|
||||
// FILETIME is 100 nanoseconds from 1601-01-01. Must be 64 bits.
|
||||
void getUnixTimeAsFileTime(FILETIME *const ts)
|
||||
void getUnixTimeAsFileTime(FILETIME* ts)
|
||||
{
|
||||
const int64_t unixtime = (int64_t)time(NULL);
|
||||
int64_t *filetime = (int64_t*)ts;
|
||||
@ -127,7 +158,7 @@ void getUnixTimeAsFileTime(FILETIME *const ts)
|
||||
PUT_UA64LE(filetime, (unixtime + 11644473600LL) * 10000000LL);
|
||||
}
|
||||
|
||||
__pure int64_t fileTimeToUnixTime(const FILETIME *const ts)
|
||||
__pure int64_t fileTimeToUnixTime(FILETIME* ts)
|
||||
{
|
||||
return GET_UA64LE(ts) / 10000000LL - 11644473600LL;
|
||||
}
|
||||
@ -255,19 +286,18 @@ static uint8_t getRandomServerType()
|
||||
{
|
||||
# if defined(USE_MSRPC) || defined(SIMPLE_RPC)
|
||||
|
||||
return rand() % vlmcsd_countof(HostBuilds);
|
||||
return rand() % KmsData->HostBuildCount;
|
||||
|
||||
# else // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
|
||||
if (!UseServerRpcBTFN)
|
||||
while (TRUE)
|
||||
{
|
||||
// This isn't possible at all, e.g. KMS host on XP
|
||||
return rand() % (int)vlmcsd_countof(HostBuilds);
|
||||
const uint32_t buildIndex = rand() % KmsData->HostBuildCount;
|
||||
|
||||
if (!(KmsData->HostBuildList[buildIndex].Flags & UseNdr64) == !UseServerRpcNDR64)
|
||||
{
|
||||
return (uint8_t)buildIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// return 9200/9600/14393/17763 if NDR64 is in use, otherwise 6002/7601
|
||||
if (UseServerRpcNDR64) return rand() % ((int)vlmcsd_countof(HostBuilds) - 2) + 2;
|
||||
return rand() % 2;
|
||||
|
||||
# endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
|
||||
}
|
||||
|
||||
@ -275,13 +305,13 @@ static uint8_t getRandomServerType()
|
||||
/*
|
||||
* Generates a random ePID
|
||||
*/
|
||||
static void generateRandomPid(const int index, char *const szPid, int16_t lang, uint16_t hostBuild)
|
||||
static void generateRandomPid(const int index, char *const szPid, int16_t lang, int32_t hostBuild)
|
||||
{
|
||||
char numberBuffer[12];
|
||||
|
||||
if (!hostBuild)
|
||||
{
|
||||
hostBuild = HostBuilds[getRandomServerType()];
|
||||
hostBuild = KmsData->HostBuildList[getRandomServerType()].BuildNumber;
|
||||
}
|
||||
|
||||
|
||||
@ -290,7 +320,7 @@ static void generateRandomPid(const int index, char *const szPid, int16_t lang,
|
||||
|
||||
//if (index > 3) index = 0;
|
||||
|
||||
const PCsvlkData_t csvlkData = &KmsData->CsvlkData[index];
|
||||
PCsvlkData_t csvlkData = &KmsData->CsvlkData[index];
|
||||
strcat(szPid, itoc(numberBuffer, csvlkData->GroupId, 5));
|
||||
strcat(szPid, "-");
|
||||
|
||||
@ -307,7 +337,8 @@ static void generateRandomPid(const int index, char *const szPid, int16_t lang,
|
||||
strcat(szPid, itoc(numberBuffer, hostBuild, 0));
|
||||
strcat(szPid, ".0000-");
|
||||
|
||||
# define minTime ((time_t)1538490811) /* Release Date Win 2019 */
|
||||
const time_t hostBuildReleaseDate = getReleaseDate(hostBuild);
|
||||
const time_t minTime = csvlkData->ReleaseDate < hostBuildReleaseDate ? hostBuildReleaseDate : csvlkData->ReleaseDate;
|
||||
|
||||
time_t maxTime;
|
||||
time(&maxTime);
|
||||
@ -343,11 +374,33 @@ void randomPidInit()
|
||||
|
||||
char Epid[PID_BUFFER_SIZE];
|
||||
|
||||
if (!HostBuild)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
#if defined(USE_MSRPC) || defined(SIMPLE_RPC)
|
||||
index = getRandomServerType();
|
||||
#else // !(defined(USE_MSRPC) || defined(SIMPLE_RPC))
|
||||
if (IsNDR64Defined)
|
||||
{
|
||||
index = getRandomServerType();
|
||||
}
|
||||
else
|
||||
{
|
||||
index = (uint8_t)(rand() % KmsData->HostBuildCount);
|
||||
UseServerRpcNDR64 = !!(KmsData->HostBuildList[index].Flags & UseNdr64);
|
||||
}
|
||||
#endif // !(defined(USE_MSRPC) || defined(SIMPLE_RPC))
|
||||
|
||||
HostBuild = (uint16_t)KmsData->HostBuildList[index].BuildNumber;
|
||||
}
|
||||
|
||||
generateRandomPid(i, Epid, lang, HostBuild);
|
||||
KmsResponseParameters[i].Epid = (const char*)vlmcsd_strdup(Epid);
|
||||
|
||||
#ifndef NO_LOG
|
||||
KmsResponseParameters[i].EpidSource = "randomized at program start";
|
||||
KmsResponseParameters[i].IsRandom = TRUE;
|
||||
#endif // NO_LOG
|
||||
}
|
||||
}
|
||||
@ -364,7 +417,7 @@ static int32_t getProductIndexFromAllLists(const GUID* guid, char** productName)
|
||||
/*
|
||||
* Logs a Request
|
||||
*/
|
||||
static void logRequest(const REQUEST *const baseRequest)
|
||||
static void logRequest(REQUEST* baseRequest)
|
||||
{
|
||||
#ifndef NO_VERBOSE_LOG
|
||||
if (logverbose)
|
||||
@ -376,7 +429,7 @@ static void logRequest(const REQUEST *const baseRequest)
|
||||
#endif // NO_VERBOSE_LOG
|
||||
|
||||
char *productName;
|
||||
char clientname[64];
|
||||
char clientName[64];
|
||||
|
||||
int32_t index = getProductIndexFromAllLists(&baseRequest->ActID, &productName);
|
||||
if (index < 0) index = getProductIndexFromAllLists(&baseRequest->KMSID, &productName);
|
||||
@ -388,8 +441,8 @@ static void logRequest(const REQUEST *const baseRequest)
|
||||
uuid2StringLE(&baseRequest->ActID, productName);
|
||||
}
|
||||
|
||||
ucs2_to_utf8(baseRequest->WorkstationName, clientname, 64, 64);
|
||||
logger("KMS v%i.%i request from %s for %s\n", LE16(baseRequest->MajorVer), LE16(baseRequest->MinorVer), clientname, productName);
|
||||
ucs2_to_utf8(baseRequest->WorkstationName, clientName, 64, 64);
|
||||
logger("KMS v%i.%i request from %s for %s\n", LE16(baseRequest->MajorVer), LE16(baseRequest->MinorVer), clientName, productName);
|
||||
}
|
||||
#endif // NO_LOG
|
||||
|
||||
@ -493,7 +546,7 @@ static void CheckRequest(const REQUEST *const Request)
|
||||
/*
|
||||
* Logs the Response
|
||||
*/
|
||||
static void logResponse(const RESPONSE *const baseResponse, const BYTE *const hwId, const char *const EpidSource)
|
||||
static void logResponse(RESPONSE* baseResponse, const BYTE *const hwId, const char *const EpidSource)
|
||||
{
|
||||
char utf8pid[PID_BUFFER_SIZE * 3];
|
||||
ucs2_to_utf8(baseResponse->KmsPID, utf8pid, PID_BUFFER_SIZE, PID_BUFFER_SIZE * 3);
|
||||
@ -525,7 +578,7 @@ long long int llabs(long long int j);
|
||||
* Creates the unencrypted base response
|
||||
*/
|
||||
#ifndef IS_LIBRARY
|
||||
static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr_unused)
|
||||
static HRESULT __stdcall CreateResponseBaseCallback(REQUEST* baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr_unused)
|
||||
{
|
||||
const char* EpidSource;
|
||||
#ifndef NO_LOG
|
||||
@ -539,7 +592,7 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
|
||||
const DWORD minClients = LE32(baseRequest->N_Policy);
|
||||
const DWORD required_clients = minClients < 1 ? 1 : minClients << 1;
|
||||
|
||||
int32_t index = getProductIndex(&baseRequest->KMSID, KmsData->KmsItemList, KmsData->KmsItemCount, NULL, &ePid);
|
||||
const int32_t index = getProductIndex(&baseRequest->KMSID, KmsData->KmsItemList, KmsData->KmsItemCount, NULL, &ePid);
|
||||
|
||||
# ifndef NO_STRICT_MODES
|
||||
|
||||
@ -554,7 +607,7 @@ static HRESULT __stdcall CreateResponseBaseCallback(const REQUEST *const baseReq
|
||||
|
||||
if (CheckClientTime)
|
||||
{
|
||||
const time_t requestTime = (time_t)fileTimeToUnixTime(&baseRequest->ClientTime);
|
||||
time_t requestTime = (time_t)fileTimeToUnixTime(&baseRequest->ClientTime);
|
||||
|
||||
if (llabs(requestTime - time(NULL)) > 60 * 60 * 4)
|
||||
{
|
||||
@ -705,21 +758,21 @@ void get16RandomBytes(void* ptr)
|
||||
/*
|
||||
* Creates v4 response
|
||||
*/
|
||||
size_t CreateResponseV4(REQUEST_V4 *const request_v4, BYTE *const responseBuffer, const char* const ipstr)
|
||||
size_t CreateResponseV4(REQUEST_V4 *const request_v4, BYTE *const responseBuffer, const char* const ipString)
|
||||
{
|
||||
RESPONSE_V4* Response = (RESPONSE_V4*)responseBuffer;
|
||||
RESPONSE_V4* response = (RESPONSE_V4*)responseBuffer;
|
||||
|
||||
HRESULT hResult;
|
||||
if (FAILED(hResult = CreateResponseBase(&request_v4->RequestBase, &Response->ResponseBase, NULL, ipstr))) return hResult;
|
||||
if (FAILED(hResult = CreateResponseBase(&request_v4->RequestBase, &response->ResponseBase, NULL, ipString))) return hResult;
|
||||
|
||||
const DWORD pidSize = LE32(Response->ResponseBase.PIDSize);
|
||||
const DWORD pidSize = LE32(response->ResponseBase.PIDSize);
|
||||
BYTE* postEpidPtr = responseBuffer + V4_PRE_EPID_SIZE + pidSize;
|
||||
memmove(postEpidPtr, &Response->ResponseBase.CMID, V4_POST_EPID_SIZE);
|
||||
memmove(postEpidPtr, &response->ResponseBase.CMID, V4_POST_EPID_SIZE);
|
||||
|
||||
const size_t encryptSize = V4_PRE_EPID_SIZE + V4_POST_EPID_SIZE + pidSize;
|
||||
AesCmacV4(responseBuffer, encryptSize, responseBuffer + encryptSize);
|
||||
|
||||
return encryptSize + sizeof(Response->MAC);
|
||||
return encryptSize + sizeof(response->MAC);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -736,7 +789,7 @@ __pure static uint64_t TimestampInterval(void *ts)
|
||||
/*
|
||||
* Creates the HMAC for v6
|
||||
*/
|
||||
static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptSize, int_fast8_t tolerance)
|
||||
static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptSize, const int_fast8_t tolerance)
|
||||
{
|
||||
BYTE hash[32];
|
||||
const uint8_t halfHashSize = sizeof(hash) >> 1;
|
||||
@ -746,7 +799,7 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
|
||||
FILETIME* ft = (FILETIME*)(responseEnd - V6_POST_EPID_SIZE + sizeof(((RESPONSE*)0)->CMID));
|
||||
|
||||
// Generate a time slot that changes every 4.11 hours.
|
||||
// Request and repsonse time must match +/- 1 slot.
|
||||
// Request and response time must match +/- 1 slot.
|
||||
// When generating a response tolerance must be 0.
|
||||
// If verifying the hash, try tolerance -1, 0 and +1. One of them must match.
|
||||
|
||||
@ -775,7 +828,7 @@ static int_fast8_t CreateV6Hmac(BYTE *const encrypt_start, const size_t encryptS
|
||||
/*
|
||||
* Creates v5 or v6 response
|
||||
*/
|
||||
size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuffer, const char* const ipstr)
|
||||
size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuffer, const char* const ipString)
|
||||
{
|
||||
// The response will be created in a fixed sized struct to
|
||||
// avoid unaligned access macros and packed structs on RISC systems
|
||||
@ -784,15 +837,15 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
|
||||
// The fixed sized struct with 64 WCHARs for the ePID will be converted
|
||||
// to a variable sized struct later and requires unaligned access macros.
|
||||
|
||||
RESPONSE_V6* Response = (RESPONSE_V6*)responseBuffer;
|
||||
RESPONSE* baseResponse = &Response->ResponseBase;
|
||||
RESPONSE_V6* response = (RESPONSE_V6*)responseBuffer;
|
||||
RESPONSE* baseResponse = &response->ResponseBase;
|
||||
|
||||
#ifdef _DEBUG
|
||||
// ReSharper disable once CppEntityNeverUsed
|
||||
// ReSharper disable once CppDeclaratorNeverUsed
|
||||
RESPONSE_V6_DEBUG* xxx_unused = (RESPONSE_V6_DEBUG*)responseBuffer;
|
||||
#endif
|
||||
|
||||
static const BYTE DefaultHwid[8] = { HWID };
|
||||
static const BYTE DefaultHwId[8] = { HWID };
|
||||
const int_fast8_t v6 = LE16(request_v6->MajorVer) > 5;
|
||||
AesCtx aesCtx;
|
||||
|
||||
@ -800,35 +853,35 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
|
||||
AesDecryptCbc(&aesCtx, NULL, request_v6->IV, V6_DECRYPT_SIZE);
|
||||
|
||||
// get random salt and SHA256 it
|
||||
get16RandomBytes(Response->RandomXoredIVs);
|
||||
Sha256(Response->RandomXoredIVs, sizeof(Response->RandomXoredIVs), Response->Hash);
|
||||
get16RandomBytes(response->RandomXoredIVs);
|
||||
Sha256(response->RandomXoredIVs, sizeof(response->RandomXoredIVs), response->Hash);
|
||||
|
||||
if (v6) // V6 specific stuff
|
||||
{
|
||||
// In v6 a random IV is generated
|
||||
Response->Version = request_v6->Version;
|
||||
get16RandomBytes(Response->IV);
|
||||
response->Version = request_v6->Version;
|
||||
get16RandomBytes(response->IV);
|
||||
|
||||
// pre-fill with default HwId (not required for v5)
|
||||
memcpy(Response->HwId, DefaultHwid, sizeof(Response->HwId));
|
||||
memcpy(response->HwId, DefaultHwId, sizeof(response->HwId));
|
||||
|
||||
// Just copy decrypted request IV (using Null IV) here. Note this is identical
|
||||
// to XORing non-decrypted request and reponse IVs
|
||||
memcpy(Response->XoredIVs, request_v6->IV, sizeof(Response->XoredIVs));
|
||||
// to XORing non-decrypted request and response IVs
|
||||
memcpy(response->XoredIVs, request_v6->IV, sizeof(response->XoredIVs));
|
||||
}
|
||||
else // V5 specific stuff
|
||||
{
|
||||
// In v5 IVs of request and response must be identical (MS client checks this)
|
||||
// The following memcpy copies Version and IVs at once
|
||||
memcpy(Response, request_v6, V6_UNENCRYPTED_SIZE);
|
||||
memcpy(response, request_v6, V6_UNENCRYPTED_SIZE);
|
||||
}
|
||||
|
||||
// Xor Random bytes with decrypted request IV
|
||||
XorBlock(request_v6->IV, Response->RandomXoredIVs);
|
||||
XorBlock(request_v6->IV, response->RandomXoredIVs);
|
||||
|
||||
// Get the base response
|
||||
HRESULT hResult;
|
||||
if (FAILED(hResult = CreateResponseBase(&request_v6->RequestBase, baseResponse, Response->HwId, ipstr))) return hResult;
|
||||
if (FAILED(hResult = CreateResponseBase(&request_v6->RequestBase, baseResponse, response->HwId, ipString))) return hResult;
|
||||
|
||||
// Convert the fixed sized struct into variable sized
|
||||
const DWORD pidSize = LE32(baseResponse->PIDSize);
|
||||
@ -840,17 +893,17 @@ size_t CreateResponseV6(REQUEST_V6 *restrict request_v6, BYTE *const responseBuf
|
||||
// number of bytes to encrypt
|
||||
size_t encryptSize =
|
||||
V6_PRE_EPID_SIZE
|
||||
- sizeof(Response->Version)
|
||||
- sizeof(response->Version)
|
||||
+ pidSize
|
||||
+ post_epid_size;
|
||||
|
||||
//AesDecryptBlock(&aesCtx, Response->IV);
|
||||
if (v6 && !CreateV6Hmac(Response->IV, encryptSize, 0)) return 0;
|
||||
if (v6 && !CreateV6Hmac(response->IV, encryptSize, 0)) return 0;
|
||||
|
||||
// Padding auto handled by encryption func
|
||||
AesEncryptCbc(&aesCtx, NULL, Response->IV, &encryptSize);
|
||||
AesEncryptCbc(&aesCtx, NULL, response->IV, &encryptSize);
|
||||
|
||||
return encryptSize + sizeof(Response->Version);
|
||||
return encryptSize + sizeof(response->Version);
|
||||
}
|
||||
|
||||
|
||||
@ -895,10 +948,10 @@ BYTE* CreateRequestV6(size_t *size, const REQUEST* requestBase)
|
||||
|
||||
// Encrypt KMS Client Request
|
||||
size_t encryptSize = sizeof(request->RequestBase);
|
||||
AesCtx Ctx;
|
||||
int_fast8_t v6 = LE16(request->MajorVer) > 5;
|
||||
AesInitKey(&Ctx, v6 ? AesKeyV6 : AesKeyV5, v6, 16);
|
||||
AesEncryptCbc(&Ctx, request->IV, (BYTE*)(&request->RequestBase), &encryptSize);
|
||||
AesCtx ctx;
|
||||
const int_fast8_t v6 = LE16(request->MajorVer) > 5;
|
||||
AesInitKey(&ctx, v6 ? AesKeyV6 : AesKeyV5, v6, 16);
|
||||
AesEncryptCbc(&ctx, request->IV, (BYTE*)(&request->RequestBase), &encryptSize);
|
||||
|
||||
// Return Proper Request Data
|
||||
return (BYTE*)request;
|
||||
@ -1045,11 +1098,11 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
|
||||
// Decrypt KMS Server Response (encrypted part starts after RequestIV)
|
||||
responseSize -= copySize1;
|
||||
|
||||
AesCtx Ctx;
|
||||
AesCtx ctx;
|
||||
const int_fast8_t v6 = LE16(((RESPONSE_V6*)response)->MajorVer) > 5;
|
||||
|
||||
AesInitKey(&Ctx, v6 ? AesKeyV6 : AesKeyV5, v6, AES_KEY_BYTES);
|
||||
AesDecryptCbc(&Ctx, NULL, response + copySize1, responseSize);
|
||||
AesInitKey(&ctx, v6 ? AesKeyV6 : AesKeyV5, v6, AES_KEY_BYTES);
|
||||
AesDecryptCbc(&ctx, NULL, response + copySize1, responseSize);
|
||||
|
||||
// Check padding
|
||||
BYTE* lastPadByte = response + (size_t)result.effectiveResponseSize - 1;
|
||||
@ -1073,7 +1126,7 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
|
||||
}
|
||||
|
||||
// Add size of Version, KmsPIDLen and variable size PID
|
||||
DWORD pidSize = LE32(((RESPONSE_V6*)response)->ResponseBase.PIDSize);
|
||||
const DWORD pidSize = LE32(((RESPONSE_V6*)response)->ResponseBase.PIDSize);
|
||||
|
||||
copySize1 +=
|
||||
V6_UNENCRYPTED_SIZE +
|
||||
@ -1097,9 +1150,9 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
|
||||
REQUEST_V6* request_v6 = (REQUEST_V6*)rawRequest;
|
||||
const DWORD decryptSize = sizeof(request_v6->IV) + sizeof(request_v6->RequestBase) + sizeof(request_v6->Pad);
|
||||
|
||||
AesDecryptCbc(&Ctx, NULL, request_v6->IV, decryptSize);
|
||||
AesDecryptCbc(&ctx, NULL, request_v6->IV, decryptSize);
|
||||
|
||||
// Check that all version informations are the same
|
||||
// Check that all version information is the same
|
||||
result.VersionOK =
|
||||
request_v6->Version == response_v6->ResponseBase.Version &&
|
||||
request_v6->Version == response_v6->Version &&
|
||||
@ -1111,14 +1164,14 @@ RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BY
|
||||
result.ClientMachineIDOK = IsEqualGUID(&response_v6->ResponseBase.CMID, &request_v6->RequestBase.CMID);
|
||||
|
||||
// Rebuild Random Key and Sha256 Hash
|
||||
BYTE HashVerify[sizeof(response_v6->Hash)];
|
||||
BYTE RandomKey[sizeof(response_v6->RandomXoredIVs)];
|
||||
BYTE hashVerify[sizeof(response_v6->Hash)];
|
||||
BYTE randomKey[sizeof(response_v6->RandomXoredIVs)];
|
||||
|
||||
memcpy(RandomKey, request_v6->IV, sizeof(RandomKey));
|
||||
XorBlock(response_v6->RandomXoredIVs, RandomKey);
|
||||
Sha256(RandomKey, sizeof(RandomKey), HashVerify);
|
||||
memcpy(randomKey, request_v6->IV, sizeof(randomKey));
|
||||
XorBlock(response_v6->RandomXoredIVs, randomKey);
|
||||
Sha256(randomKey, sizeof(randomKey), hashVerify);
|
||||
|
||||
result.HashOK = !memcmp(response_v6->Hash, HashVerify, sizeof(HashVerify));
|
||||
result.HashOK = !memcmp(response_v6->Hash, hashVerify, sizeof(hashVerify));
|
||||
|
||||
// size before encryption (padding not included)
|
||||
result.correctResponseSize =
|
||||
|
68
src/kms.h
68
src/kms.h
@ -228,6 +228,14 @@ typedef union
|
||||
|
||||
typedef BYTE hwid_t[8];
|
||||
|
||||
typedef enum
|
||||
{
|
||||
None = 0,
|
||||
UseNdr64 = 1 << 0,
|
||||
UseForEpid = 1 << 1,
|
||||
MayBeServer = 1 << 2,
|
||||
} HostBuildFlag;
|
||||
|
||||
typedef struct CsvlkData
|
||||
{
|
||||
union
|
||||
@ -236,6 +244,7 @@ typedef struct CsvlkData
|
||||
char* EPid;
|
||||
};
|
||||
|
||||
int64_t ReleaseDate;
|
||||
uint32_t GroupId;
|
||||
uint32_t MinKeyId;
|
||||
uint32_t MaxKeyId;
|
||||
@ -280,6 +289,22 @@ typedef struct
|
||||
|
||||
#define KMS_OPTIONS_USENDR64 1 << 0
|
||||
|
||||
typedef struct HostBuild
|
||||
{
|
||||
union
|
||||
{
|
||||
uint64_t DisplayNameOffset;
|
||||
char* DisplayName;
|
||||
};
|
||||
|
||||
int64_t ReleaseDate;
|
||||
int32_t BuildNumber;
|
||||
int32_t PlatformId;
|
||||
HostBuildFlag Flags;
|
||||
uint8_t reserved[4];
|
||||
|
||||
} HostBuild_t, *PHostBuild_t;
|
||||
|
||||
typedef struct VlmcsdHeader
|
||||
{
|
||||
BYTE Magic[4];
|
||||
@ -290,19 +315,21 @@ typedef struct VlmcsdHeader
|
||||
|
||||
union
|
||||
{
|
||||
int32_t Counts[3];
|
||||
int32_t Counts[5];
|
||||
|
||||
struct
|
||||
{
|
||||
int32_t AppItemCount;
|
||||
int32_t KmsItemCount;
|
||||
int32_t SkuItemCount;
|
||||
int32_t HostBuildCount;
|
||||
int32_t reserved2Counts;
|
||||
};
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
DataPointer_t Datapointers[3];
|
||||
DataPointer_t Datapointers[5];
|
||||
|
||||
struct
|
||||
{
|
||||
@ -324,19 +351,31 @@ typedef struct VlmcsdHeader
|
||||
PVlmcsdData_t SkuItemList;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
uint64_t HostBuildOffset;
|
||||
PHostBuild_t HostBuildList;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
uint64_t Reserved2Offset;
|
||||
void* Reserved2List;
|
||||
};
|
||||
|
||||
CsvlkData_t CsvlkData[1];
|
||||
};
|
||||
};
|
||||
|
||||
} VlmcsdHeader_t, *PVlmcsdHeader_t;
|
||||
|
||||
#define EPID_INDEX_WINDOWS 0
|
||||
#define EPID_INDEX_OFFICE2010 1
|
||||
#define EPID_INDEX_OFFICE2013 2
|
||||
#define EPID_INDEX_OFFICE2016 3
|
||||
#define EPID_INDEX_WINCHINAGOV 4
|
||||
//#define EPID_INDEX_WINDOWS 0
|
||||
//#define EPID_INDEX_OFFICE2010 1
|
||||
//#define EPID_INDEX_OFFICE2013 2
|
||||
//#define EPID_INDEX_OFFICE2016 3
|
||||
//#define EPID_INDEX_WINCHINAGOV 4
|
||||
|
||||
typedef HRESULT(__stdcall *RequestCallback_t)(const REQUEST *const baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
|
||||
typedef HRESULT(__stdcall *RequestCallback_t)(REQUEST* baseRequest, RESPONSE *const baseResponse, BYTE *const hwId, const char* const ipstr);
|
||||
|
||||
size_t CreateResponseV4(REQUEST_V4 *const Request, BYTE *const response_data, const char* const ipstr);
|
||||
size_t CreateResponseV6(REQUEST_V6 *restrict Request, BYTE *const response_data, const char* const ipstr);
|
||||
@ -344,13 +383,16 @@ BYTE *CreateRequestV4(size_t *size, const REQUEST* requestBase);
|
||||
BYTE *CreateRequestV6(size_t *size, const REQUEST* requestBase);
|
||||
void randomPidInit();
|
||||
void get16RandomBytes(void* ptr);
|
||||
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* Response_v6, int responseSize, BYTE* const response, const BYTE* const request, BYTE* hwid);
|
||||
RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* Response_v4, const int responseSize, BYTE* const response, const BYTE* const request);
|
||||
void getUnixTimeAsFileTime(FILETIME *const ts);
|
||||
__pure int64_t fileTimeToUnixTime(const FILETIME *const ts);
|
||||
RESPONSE_RESULT DecryptResponseV6(RESPONSE_V6* response_v6, int responseSize, BYTE* const response, const BYTE* const rawRequest, BYTE* hwid);
|
||||
RESPONSE_RESULT DecryptResponseV4(RESPONSE_V4* response_v4, const int responseSize, BYTE* const rawResponse, const BYTE* const rawRequest);
|
||||
void getUnixTimeAsFileTime(FILETIME* ts);
|
||||
__pure int64_t fileTimeToUnixTime(FILETIME* ts);
|
||||
|
||||
#ifndef IS_LIBRARY
|
||||
int32_t getProductIndex(const GUID* guid, const PVlmcsdData_t list, const int32_t count, char** name, char** ePid);
|
||||
#if !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
|
||||
const char* getNextString(const char* s);
|
||||
#endif // !defined(NO_INI_FILE)||!defined(NO_VERBOSE_LOG)
|
||||
#endif // IS_LIBRARY
|
||||
|
||||
#ifndef NO_STRICT_MODES
|
||||
@ -362,7 +404,7 @@ extern RequestCallback_t CreateResponseBase;
|
||||
|
||||
#ifdef _PEDANTIC
|
||||
uint16_t IsValidLcid(const uint16_t lcid);
|
||||
uint16_t IsValidHostBuild(const uint16_t hostBuild);
|
||||
uint32_t IsValidHostBuild(const int32_t hostBuild);
|
||||
#endif // _PEDANTIC
|
||||
|
||||
#endif // __kms_h
|
||||
|
1853
src/kmsdata-full.c
1853
src/kmsdata-full.c
File diff suppressed because it is too large
Load Diff
2195
src/kmsdata.c
2195
src/kmsdata.c
File diff suppressed because it is too large
Load Diff
@ -171,7 +171,7 @@ RpcStatus closeRpc(const RpcCtx handle)
|
||||
|
||||
#if !MULTI_CALL_BINARY
|
||||
// Memory allocation function for RPC.
|
||||
void *__RPC_USER midl_user_allocate(SIZE_T len)
|
||||
void *__RPC_USER midl_user_allocate(size_t len)
|
||||
{
|
||||
return vlmcsd_malloc(len);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ int ProcessActivationRequest(handle_t IDL_handle, int requestSize, unsigned char
|
||||
|
||||
|
||||
// Memory allocation function for RPC.
|
||||
void *__RPC_USER midl_user_allocate(SIZE_T len)
|
||||
void *__RPC_USER midl_user_allocate(size_t len)
|
||||
{
|
||||
return vlmcsd_malloc(len);
|
||||
}
|
||||
|
@ -247,7 +247,7 @@ ns_name_unpack_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src
|
||||
* Root domain returns as "." not "".
|
||||
*/
|
||||
int
|
||||
ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
|
||||
ns_name_uncompress_vlmcsd(uint8_t *msg, uint8_t *eom, uint8_t *src,
|
||||
char *dst, size_t dstsiz)
|
||||
{
|
||||
uint8_t tmp[NS_MAXCDNAME];
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define NS_NAME_H_
|
||||
|
||||
int
|
||||
ns_name_uncompress_vlmcsd(const uint8_t *msg, const uint8_t *eom, const uint8_t *src,
|
||||
ns_name_uncompress_vlmcsd(uint8_t *msg, uint8_t *eom, uint8_t *src,
|
||||
char *dst, size_t dstsiz);
|
||||
|
||||
#endif /* NS_NAME_H_ */
|
||||
|
@ -57,9 +57,9 @@
|
||||
static void setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect);
|
||||
|
||||
|
||||
static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
|
||||
static int dn_skipname_vlmcsd(unsigned char *s, unsigned char *end)
|
||||
{
|
||||
const unsigned char *p;
|
||||
unsigned char *p;
|
||||
for (p=s; p<end; p++)
|
||||
if (!*p) return p-s+1;
|
||||
else if (*p>=192)
|
||||
@ -69,8 +69,8 @@ static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
|
||||
}
|
||||
|
||||
static int
|
||||
ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section, int count) {
|
||||
const uint8_t *optr = ptr;
|
||||
ns_skiprr_vlmcsd(uint8_t *ptr, uint8_t *eom, ns_sect_vlmcsd section, int count) {
|
||||
uint8_t *optr = ptr;
|
||||
|
||||
for ((void)NULL; count > 0; count--) {
|
||||
int b, rdlength;
|
||||
@ -93,8 +93,8 @@ ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section,
|
||||
}
|
||||
|
||||
int
|
||||
ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
|
||||
const uint8_t *eom = msg + msglen;
|
||||
ns_initparse_vlmcsd(uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
|
||||
uint8_t *eom = msg + msglen;
|
||||
int i;
|
||||
|
||||
memset(handle, 0x5e, sizeof *handle);
|
||||
|
@ -46,12 +46,12 @@ typedef enum __ns_sect_vlmcsd {
|
||||
} ns_sect_vlmcsd;
|
||||
|
||||
typedef struct __ns_msg_vlmcsd {
|
||||
const uint8_t *_msg, *_eom;
|
||||
uint8_t *_msg, *_eom;
|
||||
uint16_t _id, _flags, _counts[ns_s_max_vlmcsd];
|
||||
const uint8_t *_sections[ns_s_max_vlmcsd];
|
||||
uint8_t *_sections[ns_s_max_vlmcsd];
|
||||
ns_sect_vlmcsd _sect;
|
||||
int _rrnum;
|
||||
const uint8_t *_msg_ptr;
|
||||
uint8_t *_msg_ptr;
|
||||
} ns_msg_vlmcsd;
|
||||
|
||||
|
||||
@ -61,10 +61,10 @@ typedef struct __ns_rr_vlmcsd {
|
||||
uint16_t rr_class;
|
||||
uint32_t ttl;
|
||||
uint16_t rdlength;
|
||||
const uint8_t * rdata;
|
||||
uint8_t * rdata;
|
||||
} ns_rr_vlmcsd;
|
||||
|
||||
int ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle);
|
||||
int ns_initparse_vlmcsd(uint8_t *msg, int msglen, ns_msg_vlmcsd *handle);
|
||||
|
||||
int ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr);
|
||||
|
||||
|
@ -180,7 +180,7 @@ void uuid2StringLE(const GUID *const guid, char *const string)
|
||||
}
|
||||
|
||||
#if !defined(NO_VERBOSE_LOG) && !defined(NO_LOG)
|
||||
void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
|
||||
void logRequestVerbose(REQUEST* Request, const PRINTFUNC p)
|
||||
{
|
||||
char guidBuffer[GUID_STRING_LENGTH + 1];
|
||||
char WorkstationBuffer[3 * WORKSTATION_NAME_BUFFER];
|
||||
@ -222,7 +222,7 @@ void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p)
|
||||
p("N count policy (minimum clients): %u\n", (uint32_t)LE32(Request->N_Policy));
|
||||
}
|
||||
|
||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p)
|
||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p)
|
||||
{
|
||||
char guidBuffer[GUID_STRING_LENGTH + 1];
|
||||
|
||||
|
@ -14,8 +14,8 @@ typedef int (*PRINTFUNC)(const char *const fmt, ...);
|
||||
|
||||
int printerrorf(const char *const fmt, ...);
|
||||
int errorout(const char* fmt, ...);
|
||||
void logRequestVerbose(const REQUEST *const Request, const PRINTFUNC p);
|
||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, const RESPONSE *const response, const PRINTFUNC p);
|
||||
void logRequestVerbose(REQUEST* Request, const PRINTFUNC p);
|
||||
void logResponseVerbose(const char *const ePID, const BYTE *const hwid, RESPONSE* response, const PRINTFUNC p);
|
||||
|
||||
#ifndef NO_VERSION_INFORMATION
|
||||
void printPlatform();
|
||||
|
@ -325,7 +325,7 @@ static int rpcRequest(const RPC_REQUEST64 *const Request, RPC_RESPONSE64 *const
|
||||
# endif // !SIMPLE_RPC
|
||||
|
||||
pRpcReturnCode = ((BYTE*)&Response->Ndr) + len;
|
||||
UA32(pRpcReturnCode) = ResponseSize < 0 ? LE32(ResponseSize) : 0;
|
||||
PUT_UA32LE(pRpcReturnCode, ResponseSize < 0 ? ResponseSize : 0);
|
||||
len += sizeof(DWORD);
|
||||
|
||||
// Pad zeros to 32-bit align (seems not neccassary but Windows RPC does it this way)
|
||||
@ -371,7 +371,7 @@ static void CheckRpcBindRequest(const RPC_BIND_REQUEST *const Request, const uns
|
||||
|
||||
if (ctxItem->InterfaceVerMajor != LE16(1) || ctxItem->InterfaceVerMinor != 0)
|
||||
logger("Warning: Interface version is %u.%u but should be 1.0.\n",
|
||||
(unsigned int)LE16(ctxItem->InterfaceVerMajor),
|
||||
(unsigned int)LE16(ctxItem->InterfaceVerMajor),
|
||||
(unsigned int)LE16(ctxItem->InterfaceVerMinor)
|
||||
);
|
||||
|
||||
@ -494,7 +494,7 @@ static int rpcBind(const RPC_BIND_REQUEST *const Request, RPC_BIND_RESPONSE* Res
|
||||
|
||||
for (i = 0; i < numCtxItems; i++)
|
||||
{
|
||||
struct CtxResults* result = Response->Results+i;
|
||||
struct CtxResults* result = Response->Results + i;
|
||||
const GUID* ctxTransferSyntax = &Request->CtxItems[i].TransferSyntax;
|
||||
|
||||
# ifndef SIMPLE_RPC
|
||||
@ -970,7 +970,8 @@ RpcStatus rpcSendRequest(const RpcCtx sock, const BYTE *const kmsRequest, const
|
||||
}
|
||||
|
||||
pReturnCode = (DWORD*)(*kmsResponse + *responseSize + pad);
|
||||
status = LE32(UA32(pReturnCode));
|
||||
status = GET_UA32LE(pReturnCode);
|
||||
//status = LE32(UA32(pReturnCode));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ typedef struct
|
||||
const BYTE* HwId;
|
||||
#ifndef NO_LOG
|
||||
const char* EpidSource;
|
||||
uint8_t IsRandom;
|
||||
#endif // NO_LOG
|
||||
} KmsResponseParam_t, *PKmsResponseParam_t;
|
||||
|
||||
|
99
src/vlmcs.c
99
src/vlmcs.c
@ -52,8 +52,6 @@
|
||||
#define VLMCS_OPTION_GRAB_INI 1
|
||||
#define VLMCS_OPTION_NO_GRAB_INI 2
|
||||
|
||||
//#define kmsVersionMinor 0 // Currently constant. May change in future KMS versions
|
||||
|
||||
#ifndef IS_LIBRARY
|
||||
|
||||
// Function Prototypes
|
||||
@ -83,24 +81,19 @@ static int AddressFamily = 0;
|
||||
static int_fast8_t incompatibleOptions = 0;
|
||||
static const char* fn_ini_client = NULL;
|
||||
//static int_fast16_t kmsVersionMinor = 0;
|
||||
static const char* ePidGroup[] = { "Windows", "Office2010", "Office2013", "Office2016" };
|
||||
//static const char* ePidGroup[] = { "Windows", "Office2010", "Office2013", "Office2016" };
|
||||
static int32_t ActiveProductIndex = 0;
|
||||
static int32_t NCountPolicy = 0;
|
||||
static GUID AppGuid, KmsGuid, SkuGuid;
|
||||
static uint16_t MinorVersion = 0;
|
||||
static uint16_t MajorVersion;
|
||||
|
||||
//#if !MULTI_CALL_BINARY
|
||||
//uint8_t DefaultKmsData[]={0};
|
||||
//__pure size_t getDefaultKmsDataSize() { return (size_t)0; }
|
||||
//#endif // !MULTI_CALL_BINARY
|
||||
|
||||
#ifndef NO_DNS
|
||||
static int_fast8_t NoSrvRecordPriority = FALSE;
|
||||
#endif // NO_DNS
|
||||
|
||||
|
||||
typedef char iniFileEpidLines[4][256];
|
||||
//typedef char iniFileEpidLines[4][256];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -943,7 +936,6 @@ static void displayRequestError(RpcCtx *const s, const int status, const int cur
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void newIniBackupFile(const char* const restrict fname)
|
||||
{
|
||||
FILE *restrict f = fopen(fname, "wb");
|
||||
@ -965,9 +957,9 @@ static void newIniBackupFile(const char* const restrict fname)
|
||||
}
|
||||
|
||||
|
||||
static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
static void updateIniFile(char*** restrict lines)
|
||||
{
|
||||
int_fast8_t lineWritten[vlmcsd_countof(*lines)];
|
||||
int_fast8_t* lineWritten = (int_fast8_t*)malloc(KmsData->CsvlkCount * sizeof(int_fast8_t));
|
||||
# if !_MSC_VER
|
||||
struct stat statbuf;
|
||||
# endif
|
||||
@ -975,7 +967,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
int_fast8_t iniFileExistedBefore = TRUE;
|
||||
unsigned int lineNumber;
|
||||
|
||||
memset(lineWritten, FALSE, sizeof(lineWritten));
|
||||
memset(lineWritten, FALSE, KmsData->CsvlkCount * sizeof(int_fast8_t));
|
||||
|
||||
char* restrict fn_bak = (char*)vlmcsd_malloc(strlen(fn_ini_client) + 2);
|
||||
|
||||
@ -1009,7 +1001,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
vlmcsd_unlink(fn_bak); // Required for Windows. Most Unix systems don't need it.
|
||||
if (rename(fn_ini_client, fn_bak))
|
||||
{
|
||||
int error = errno;
|
||||
const int error = errno;
|
||||
errorout("Fatal: Cannot create %s: %s\n", fn_bak, strerror(error));
|
||||
exit(error);
|
||||
}
|
||||
@ -1023,7 +1015,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
|
||||
if (!in)
|
||||
{
|
||||
int error = errno;
|
||||
const int error = errno;
|
||||
errorout("Fatal: Cannot open %s: %s\n", fn_bak, strerror(error));
|
||||
exit(error);
|
||||
}
|
||||
@ -1032,7 +1024,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
|
||||
if (!out)
|
||||
{
|
||||
int error = errno;
|
||||
const int error = errno;
|
||||
errorout("Fatal: Cannot create %s: %s\n", fn_ini_client, strerror(error));
|
||||
exit(error);
|
||||
}
|
||||
@ -1041,9 +1033,9 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
|
||||
for (lineNumber = 1; fgets(sourceLine, sizeof(sourceLine), in); lineNumber++)
|
||||
{
|
||||
for (i = 0; i < vlmcsd_countof(*lines); i++)
|
||||
for (i = 0; i < KmsData->CsvlkCount; i++)
|
||||
{
|
||||
if (*(*lines)[i] && !strncasecmp(sourceLine, (*lines)[i], strlen(ePidGroup[i])))
|
||||
if (*(*lines)[i] && !strncasecmp(sourceLine, (*lines)[i], strlen(getNextString((KmsData->CsvlkData[i].EPid)))))
|
||||
{
|
||||
if (lineWritten[i]) break;
|
||||
|
||||
@ -1054,7 +1046,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= vlmcsd_countof(*lines))
|
||||
if (i >= KmsData->CsvlkCount)
|
||||
{
|
||||
fprintf(out, "%s", sourceLine);
|
||||
}
|
||||
@ -1069,7 +1061,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
|
||||
fclose(in);
|
||||
|
||||
for (i = 0; i < vlmcsd_countof(*lines); i++)
|
||||
for (i = 0; i < KmsData->CsvlkCount; i++)
|
||||
{
|
||||
if (!lineWritten[i] && *(*lines)[i])
|
||||
{
|
||||
@ -1080,7 +1072,7 @@ static void updateIniFile(iniFileEpidLines* const restrict lines)
|
||||
|
||||
if (fclose(out))
|
||||
{
|
||||
int error = errno;
|
||||
const int error = errno;
|
||||
errorout("Fatal: Cannot write to %s: %s\n", fn_ini_client, strerror(error));
|
||||
exit(error);
|
||||
}
|
||||
@ -1095,18 +1087,27 @@ static void grabServerData()
|
||||
{
|
||||
RpcCtx s = INVALID_RPCCTX;
|
||||
WORD MajorVer = 6;
|
||||
iniFileEpidLines lines;
|
||||
|
||||
static char* Licenses[vlmcsd_countof(lines)] =
|
||||
{
|
||||
(char*)"212a64dc-43b1-4d3d-a30c-2fc69d2095c6", // Vista
|
||||
(char*)"e85af946-2e25-47b7-83e1-bebcebeac611", // Office 2010
|
||||
(char*)"e6a6f1bf-9d40-40c3-aa9f-c77ba21578c0", // Office 2013
|
||||
(char*)"85b5f61b-320b-4be3-814a-b76b2bfafc82", // Office 2016
|
||||
};
|
||||
|
||||
uint_fast8_t i;
|
||||
int32_t i;
|
||||
int32_t j;
|
||||
|
||||
char** lines = (char**)vlmcsd_malloc(KmsData->CsvlkCount * sizeof(char*));
|
||||
GUID* kmsGuids = (GUID*)vlmcsd_malloc(KmsData->CsvlkCount * sizeof(GUID));
|
||||
|
||||
for (i = 0; i < KmsData->CsvlkCount; i++)
|
||||
{
|
||||
lines[i] = (char*)vlmcsd_malloc(256);
|
||||
*lines[i] = 0;
|
||||
|
||||
for (j = 0; j < KmsData->KmsItemCount; j++)
|
||||
{
|
||||
if (KmsData->KmsItemList[j].EPidIndex == i)
|
||||
{
|
||||
kmsGuids[i] = KmsData->KmsItemList[j].Guid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RESPONSE response;
|
||||
RESPONSE_RESULT result;
|
||||
REQUEST request;
|
||||
@ -1114,23 +1115,19 @@ static void grabServerData()
|
||||
int status;
|
||||
size_t len;
|
||||
|
||||
for (i = 0; i < vlmcsd_countof(lines); i++) *lines[i] = 0;
|
||||
|
||||
for (i = 0; i < vlmcsd_countof(Licenses) && MajorVer > 3; i++)
|
||||
for (i = 0; i < KmsData->CsvlkCount && MajorVer > 3; i++)
|
||||
{
|
||||
GUID guid;
|
||||
string2UuidLE(Licenses[i], &guid);
|
||||
int32_t kmsIndex = getProductIndex(&guid, KmsData->KmsItemList, KmsData->KmsItemCount, NULL, NULL);
|
||||
const int32_t kmsIndex = getProductIndex(&kmsGuids[i], KmsData->KmsItemList, KmsData->KmsItemCount, NULL, NULL);
|
||||
|
||||
if (kmsIndex < 0)
|
||||
{
|
||||
errorout("Warning: KMS GUID %s not in database.\n", Licenses[i]);
|
||||
errorout("Warning: KMS GUID not in database.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ActiveProductIndex = ~0;
|
||||
|
||||
for (j = KmsData->SkuItemCount; j >= 0; j--)
|
||||
for (j = KmsData->SkuItemCount - 1; j >= 0; j--)
|
||||
{
|
||||
if (KmsData->SkuItemList[j].KmsIndex == kmsIndex)
|
||||
{
|
||||
@ -1141,11 +1138,11 @@ static void grabServerData()
|
||||
|
||||
if (ActiveProductIndex == ~0)
|
||||
{
|
||||
errorout("Warning: KMS GUID %s not in database.\n", Licenses[i]);
|
||||
errorout("Warning: KMS GUID not in database.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t appIndex = KmsData->SkuItemList[ActiveProductIndex].AppIndex;
|
||||
const int32_t appIndex = KmsData->SkuItemList[ActiveProductIndex].AppIndex;
|
||||
|
||||
NCountPolicy = (uint32_t)KmsData->SkuItemList[ActiveProductIndex].NCountPolicy;
|
||||
memcpy(&SkuGuid, &KmsData->SkuItemList[ActiveProductIndex].Guid, sizeof(GUID));
|
||||
@ -1154,7 +1151,7 @@ static void grabServerData()
|
||||
MajorVersion = (uint16_t)MajorVer;
|
||||
|
||||
status = sendRequest(&s, &request, &response, hwid, &result);
|
||||
printf("%-11s", ePidGroup[i]);
|
||||
printf("%-11s", getNextString(KmsData->CsvlkData[i].EPid));
|
||||
|
||||
if (status)
|
||||
{
|
||||
@ -1171,7 +1168,7 @@ static void grabServerData()
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("%i of %i", (int)(i + 7 - MajorVer), (int)(10 - MajorVer));
|
||||
printf("%i of %i", (int)(i + 7 - MajorVer), (int)(KmsData->CsvlkCount + 6 - MajorVer));
|
||||
displayResponse(result, &request, &response, hwid);
|
||||
|
||||
char ePID[3 * PID_BUFFER_SIZE];
|
||||
@ -1181,16 +1178,16 @@ static void grabServerData()
|
||||
memset(ePID + 3 * PID_BUFFER_SIZE - 3, 0, 3);
|
||||
}
|
||||
|
||||
vlmcsd_snprintf(lines[i], sizeof(lines[0]), "%s = %s", ePidGroup[i], ePID);
|
||||
vlmcsd_snprintf(lines[i], 255 - strlen(lines[i]), "%s = %s", getNextString(KmsData->CsvlkData[i].EPid), ePID);
|
||||
|
||||
if (response.MajorVer > 5)
|
||||
{
|
||||
len = strlen(lines[i]);
|
||||
vlmcsd_snprintf(lines[i] + len, sizeof(lines[0]) - len, " / %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
|
||||
vlmcsd_snprintf(lines[i] + len, 255 - len, " / %02X %02X %02X %02X %02X %02X %02X %02X", hwid[0], hwid[1], hwid[2], hwid[3], hwid[4], hwid[5], hwid[6], hwid[7]);
|
||||
}
|
||||
|
||||
len = strlen(lines[i]);
|
||||
vlmcsd_snprintf(lines[i] + len, sizeof(lines[0]) - len, "\n");
|
||||
vlmcsd_snprintf(lines[i] + len, 255 - len, "\n");
|
||||
|
||||
}
|
||||
|
||||
@ -1201,7 +1198,7 @@ static void grabServerData()
|
||||
else
|
||||
{
|
||||
printf("\n");
|
||||
for (i = 0; i < vlmcsd_countof(lines); i++) printf("%s", lines[i]);
|
||||
for (i = 0; i < KmsData->CsvlkCount; i++) printf("%s", lines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1212,10 +1209,10 @@ int client_main(int argc, CARGV argv)
|
||||
|
||||
// Windows Sockets must be initialized
|
||||
|
||||
WSADATA wsadata;
|
||||
WSADATA wsaData;
|
||||
int error;
|
||||
|
||||
if ((error = WSAStartup(0x0202, &wsadata)))
|
||||
if ((error = WSAStartup(0x0202, &wsaData)))
|
||||
{
|
||||
errorout("Fatal: Could not initialize Windows sockets (Error: %d).\n", error);
|
||||
return error;
|
||||
@ -1245,7 +1242,7 @@ int client_main(int argc, CARGV argv)
|
||||
else
|
||||
useDefaultHost = TRUE;
|
||||
|
||||
int hostportarg = optind;
|
||||
const int hostportarg = optind;
|
||||
|
||||
if (optind < argc - 1)
|
||||
{
|
||||
|
189
src/vlmcsd.c
189
src/vlmcsd.c
@ -93,21 +93,23 @@ static uint_fast8_t maxsockets = 0;
|
||||
|
||||
#ifdef _NTSERVICE
|
||||
static int_fast8_t installService = 0;
|
||||
static const char *restrict ServiceUser = NULL;
|
||||
static const char *restrict ServicePassword = "";
|
||||
static const char* restrict ServiceUser = NULL;
|
||||
static const char* restrict ServicePassword = "";
|
||||
#endif
|
||||
|
||||
#ifndef NO_PID_FILE
|
||||
static const char *fn_pid = NULL;
|
||||
static const char* fn_pid = NULL;
|
||||
#endif
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
#if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
#ifdef INI_FILE
|
||||
static const char *fn_ini = INI_FILE;
|
||||
static const char* fn_ini = INI_FILE;
|
||||
#else // !INI_FILE
|
||||
static const char *fn_ini = NULL;
|
||||
static const char* fn_ini = NULL;
|
||||
#endif // !INI_FILE
|
||||
#endif // NO_INI_FILE
|
||||
|
||||
#ifndef NO_TAP
|
||||
char* tapArgument = NULL;
|
||||
@ -203,12 +205,12 @@ static int shmid = -1;
|
||||
#ifndef NO_USER_SWITCH
|
||||
#ifndef _WIN32
|
||||
|
||||
static const char *uname = NULL, *gname = NULL;
|
||||
static const char* uname = NULL, * gname = NULL;
|
||||
static gid_t gid = INVALID_GID;
|
||||
static uid_t uid = INVALID_UID;
|
||||
|
||||
// Get Numeric id of user/group
|
||||
static char GetNumericId(gid_t *restrict id, const char *const c)
|
||||
static char GetNumericId(gid_t* restrict id, const char* const c)
|
||||
{
|
||||
char* endptr;
|
||||
gid_t temp;
|
||||
@ -224,7 +226,7 @@ static char GetNumericId(gid_t *restrict id, const char *const c)
|
||||
// Get group id from option argument
|
||||
static char GetGid()
|
||||
{
|
||||
struct group *g;
|
||||
struct group* g;
|
||||
|
||||
if ((g = getgrnam(optarg)))
|
||||
gid = g->gr_gid;
|
||||
@ -238,7 +240,7 @@ static char GetGid()
|
||||
// Get user id from option argument
|
||||
static char GetUid()
|
||||
{
|
||||
struct passwd *u;
|
||||
struct passwd* u;
|
||||
|
||||
////PORTABILITY: Assumes uid_t and gid_t are of same size (shouldn't be a problem)
|
||||
if ((u = getpwnam(optarg)))
|
||||
@ -380,9 +382,9 @@ static __noreturn void usage()
|
||||
|
||||
|
||||
#ifndef NO_CUSTOM_INTERVALS
|
||||
#ifndef NO_INI_FILE
|
||||
#if !defined(NO_INI_FILE)
|
||||
|
||||
__pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restrict argument)
|
||||
__pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char* const restrict argument)
|
||||
{
|
||||
const DWORD val = timeSpanString2Minutes(argument);
|
||||
|
||||
@ -396,10 +398,10 @@ __pure static BOOL getTimeSpanFromIniFile(DWORD* result, const char *const restr
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif // NO_INI_FILE
|
||||
#endif // !defined(NO_INI_FILE)
|
||||
|
||||
|
||||
__pure static DWORD getTimeSpanFromCommandLine(const char *const restrict arg, const char optchar)
|
||||
__pure static DWORD getTimeSpanFromCommandLine(const char* const restrict arg, const char optchar)
|
||||
{
|
||||
const DWORD val = timeSpanString2Minutes(arg);
|
||||
|
||||
@ -424,13 +426,13 @@ static __pure int isControlCharOrSlash(const char c)
|
||||
}
|
||||
|
||||
|
||||
static void iniFileLineNextWord(const char **s)
|
||||
static void iniFileLineNextWord(const char** s)
|
||||
{
|
||||
while (**s && isspace((int)**s)) (*s)++;
|
||||
}
|
||||
|
||||
|
||||
static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index, const uint8_t overwrite)
|
||||
static BOOL setHwIdFromIniFileLine(const char** s, const uint32_t index, const uint8_t overwrite)
|
||||
{
|
||||
iniFileLineNextWord(s);
|
||||
|
||||
@ -438,8 +440,8 @@ static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index, const u
|
||||
{
|
||||
if (!overwrite && KmsResponseParameters[index].HwId) return TRUE;
|
||||
|
||||
BYTE* HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6 *)0)->HwId));
|
||||
hex2bin(HwId, *s + 1, sizeof(((RESPONSE_V6 *)0)->HwId));
|
||||
BYTE* HwId = (BYTE*)vlmcsd_malloc(sizeof(((RESPONSE_V6*)0)->HwId));
|
||||
hex2bin(HwId, *s + 1, sizeof(((RESPONSE_V6*)0)->HwId));
|
||||
KmsResponseParameters[index].HwId = HwId;
|
||||
}
|
||||
|
||||
@ -447,10 +449,10 @@ static BOOL setHwIdFromIniFileLine(const char **s, const uint32_t index, const u
|
||||
}
|
||||
|
||||
|
||||
static BOOL setEpidFromIniFileLine(const char **s, const uint32_t index, const char *ePidSource, const uint8_t overwrite)
|
||||
static BOOL setEpidFromIniFileLine(const char** s, const uint32_t index, const char* ePidSource, const uint8_t overwrite)
|
||||
{
|
||||
iniFileLineNextWord(s);
|
||||
const char *savedPosition = *s;
|
||||
const char* savedPosition = *s;
|
||||
uint_fast16_t i;
|
||||
|
||||
for (i = 0; !isControlCharOrSlash(**s); i++)
|
||||
@ -478,34 +480,16 @@ static BOOL setEpidFromIniFileLine(const char **s, const uint32_t index, const c
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif // !defined(NO_INI_FILE) || !defined (NO_CL_PIDS)
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
static void ignoreIniFileParameter(uint_fast8_t iniFileParameterId)
|
||||
{
|
||||
uint_fast8_t i;
|
||||
|
||||
for (i = 0; i < vlmcsd_countof(IniFileParameterList); i++)
|
||||
{
|
||||
if (IniFileParameterList[i].Id != iniFileParameterId) continue;
|
||||
IniFileParameterList[i].Id = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else // NO_INI_FILE
|
||||
#define ignoreIniFileParameter(x)
|
||||
#endif // NO_INI_FILE
|
||||
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
static BOOL getIniFileArgumentBool(int_fast8_t *result, const char *const argument)
|
||||
static BOOL getIniFileArgumentBool(int_fast8_t* result, const char* const argument)
|
||||
{
|
||||
IniFileErrorMessage = "Argument must be true/on/yes/1 or false/off/no/0";
|
||||
return getArgumentBool(result, argument);
|
||||
}
|
||||
|
||||
|
||||
static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argument, const unsigned int min, const unsigned int max)
|
||||
static BOOL getIniFileArgumentInt(unsigned int* result, const char* const argument, const unsigned int min, const unsigned int max)
|
||||
{
|
||||
unsigned int tempResult;
|
||||
|
||||
@ -521,7 +505,7 @@ static BOOL getIniFileArgumentInt(unsigned int *result, const char *const argume
|
||||
}
|
||||
|
||||
|
||||
static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
|
||||
static BOOL setIniFileParameter(uint_fast8_t id, const char* const iniarg)
|
||||
{
|
||||
unsigned int result;
|
||||
BOOL success = TRUE;
|
||||
@ -539,7 +523,7 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
|
||||
|
||||
case INI_PARAM_GID:
|
||||
{
|
||||
struct group *g;
|
||||
struct group* g;
|
||||
IniFileErrorMessage = "Invalid group id or name";
|
||||
if (!(gname = vlmcsd_strdup(iniarg))) return FALSE;
|
||||
|
||||
@ -552,7 +536,7 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
|
||||
|
||||
case INI_PARAM_UID:
|
||||
{
|
||||
struct passwd *p;
|
||||
struct passwd* p;
|
||||
IniFileErrorMessage = "Invalid user id or name";
|
||||
if (!(uname = vlmcsd_strdup(iniarg))) return FALSE;
|
||||
|
||||
@ -749,9 +733,11 @@ static BOOL setIniFileParameter(uint_fast8_t id, const char *const iniarg)
|
||||
|
||||
return success;
|
||||
}
|
||||
#endif // !NO_INI_FILE
|
||||
|
||||
|
||||
static BOOL getIniFileArgument(const char **s)
|
||||
|
||||
static BOOL getIniFileArgument(const char** s)
|
||||
{
|
||||
while (!isspace((int)**s) && **s != '=' && **s) (*s)++;
|
||||
iniFileLineNextWord(s);
|
||||
@ -773,18 +759,14 @@ static BOOL getIniFileArgument(const char **s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char* GetNextString(char* s)
|
||||
{
|
||||
return s + strlen(s) + 1;
|
||||
}
|
||||
|
||||
static int8_t GetCsvlkIndexFromName(const char *s)
|
||||
static int8_t GetCsvlkIndexFromName(const char* s)
|
||||
{
|
||||
int8_t i;
|
||||
|
||||
for (i = 0; i < KmsData->CsvlkCount; i++)
|
||||
{
|
||||
const char *csvlkName = GetNextString(KmsData->CsvlkData[i].EPid);
|
||||
const char* csvlkName = getNextString(KmsData->CsvlkData[i].EPid);
|
||||
|
||||
if (!strncasecmp(csvlkName, s, strlen(csvlkName)))
|
||||
{
|
||||
@ -795,7 +777,7 @@ static int8_t GetCsvlkIndexFromName(const char *s)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static BOOL handleIniFileEpidParameter(const char *s, uint8_t allowIniFileDirectives, const char *ePidSource)
|
||||
static BOOL handleIniFileEpidParameter(const char* s, uint8_t allowIniFileDirectives, const char* ePidSource)
|
||||
{
|
||||
int_fast16_t i;
|
||||
|
||||
@ -824,7 +806,26 @@ static BOOL handleIniFileEpidParameter(const char *s, uint8_t allowIniFileDirect
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL handleIniFileParameter(const char *s)
|
||||
#endif // !defined(NO_INI_FILE) || !defined (NO_CL_PIDS)
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
static void ignoreIniFileParameter(uint_fast8_t iniFileParameterId)
|
||||
{
|
||||
uint_fast8_t i;
|
||||
|
||||
for (i = 0; i < vlmcsd_countof(IniFileParameterList); i++)
|
||||
{
|
||||
if (IniFileParameterList[i].Id != iniFileParameterId) continue;
|
||||
IniFileParameterList[i].Id = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else // NO_INI_FILE
|
||||
#define ignoreIniFileParameter(x)
|
||||
#endif // NO_INI_FILE
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
static BOOL handleIniFileParameter(const char* s)
|
||||
{
|
||||
uint_fast8_t i;
|
||||
|
||||
@ -843,7 +844,7 @@ static BOOL handleIniFileParameter(const char *s)
|
||||
|
||||
|
||||
#if !defined(NO_SOCKETS) && !defined(SIMPLE_SOCKETS) && !defined(USE_MSRPC)
|
||||
static BOOL setupListeningSocketsFromIniFile(const char *s)
|
||||
static BOOL setupListeningSocketsFromIniFile(const char* s)
|
||||
{
|
||||
if (!maxsockets) return TRUE;
|
||||
if (strncasecmp("Listen", s, 6)) return TRUE;
|
||||
@ -859,26 +860,31 @@ static BOOL setupListeningSocketsFromIniFile(const char *s)
|
||||
static BOOL readIniFile(const uint_fast8_t pass)
|
||||
{
|
||||
char line[256];
|
||||
const char *s;
|
||||
const char* s;
|
||||
unsigned int lineNumber;
|
||||
uint_fast8_t lineParseError;
|
||||
|
||||
FILE *restrict f;
|
||||
FILE* restrict f;
|
||||
BOOL result = TRUE;
|
||||
|
||||
if (pass == INI_FILE_PASS_2 && KmsData->MinorVer < 6)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
IniFileErrorBuffer = (char*)vlmcsd_malloc(INIFILE_ERROR_BUFFERSIZE);
|
||||
|
||||
if (!((f = fopen(fn_ini, "r")))) return FALSE;
|
||||
|
||||
for (lineNumber = 1; (s = fgets(line, sizeof(line), f)); lineNumber++)
|
||||
{
|
||||
line[strlen(line) - 1] = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = strlen(line); i > 0; i--)
|
||||
{
|
||||
if (line[i - 1] != 0xd && line[i - 1] != 0xa)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line[i] = 0;
|
||||
|
||||
iniFileLineNextWord(&s);
|
||||
if (*s == ';' || *s == '#' || !*s) continue;
|
||||
|
||||
@ -965,7 +971,7 @@ __noreturn static void HangupHandler(const int signal_unused)
|
||||
}
|
||||
|
||||
argv_out[argc_in] = argv_out[argc_in + 1] = NULL;
|
||||
if (daemonize_protection) argv_out[argc_in] = (char*) "-Z";
|
||||
if (daemonize_protection) argv_out[argc_in] = (char*)"-Z";
|
||||
|
||||
exec_self((char**)argv_out);
|
||||
int error = errno;
|
||||
@ -1084,7 +1090,7 @@ static DWORD daemonizeAndSetSignalAction()
|
||||
// Workaround for Cygwin fork problem (only affects cygwin processes that are Windows services)
|
||||
// Best is to compile for Cygwin with threads. fork() is slow and unreliable on Cygwin
|
||||
#if !defined(NO_INI_FILE) || !defined(NO_LOG) || !defined(NO_CL_PIDS) || !defined(NO_EXTERNAL_DATA)
|
||||
__pure static char* getCommandLineArg(char *const restrict arg)
|
||||
__pure static char* getCommandLineArg(char* const restrict arg)
|
||||
{
|
||||
# if !__CYGWIN__ || defined(USE_THREADS) || defined(NO_SOCKETS)
|
||||
return arg;
|
||||
@ -1325,14 +1331,6 @@ static void parseGeneralArguments() {
|
||||
case 'H':
|
||||
HostBuild = (uint16_t)getOptionArgumentInt((char)o, 0, 0xffff);
|
||||
ignoreIniFileParameter(INI_PARAM_HOST_BUILD);
|
||||
|
||||
# ifdef _PEDANTIC
|
||||
if (!IsValidHostBuild(HostBuild))
|
||||
{
|
||||
printerrorf("Warning: %u is not a known released Windows Server build >= 2008.\n");
|
||||
}
|
||||
# endif // _PEDANTIC
|
||||
|
||||
break;
|
||||
# endif // NO_RANDOM_PID
|
||||
|
||||
@ -1437,7 +1435,7 @@ static void writePidFile()
|
||||
|
||||
if (fn_pid && !InetdMode)
|
||||
{
|
||||
FILE *file = fopen(fn_pid, "w");
|
||||
FILE* file = fopen(fn_pid, "w");
|
||||
|
||||
if (file)
|
||||
{
|
||||
@ -1455,8 +1453,8 @@ static void writePidFile()
|
||||
logger("Warning: Cannot write pid file '%s'. %s.\n", fn_pid, strerror(errno));
|
||||
}
|
||||
# endif // NO_LOG
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define writePidFile()
|
||||
#endif // !defined(NO_PID_FILE)
|
||||
@ -1563,8 +1561,8 @@ static void allocateSemaphore(void)
|
||||
{
|
||||
printerrorf("Warning: Could not create semaphore: %s\n", vlmcsd_strerror(errno));
|
||||
MaxTasks = SEM_VALUE_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# endif // THREADS or CYGWIN
|
||||
|
||||
@ -1577,7 +1575,7 @@ static void allocateSemaphore(void)
|
||||
}
|
||||
|
||||
# endif // _WIN32
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !defined(NO_LIMIT) && !defined(NO_SOCKETS) && !__minix__
|
||||
|
||||
@ -1656,7 +1654,7 @@ int setupListeningSockets()
|
||||
if (haveIPv6Stack) addListeningSocket("::");
|
||||
if (haveIPv4Stack) addListeningSocket("0.0.0.0");
|
||||
# endif // !HAVE_GETIFADDR
|
||||
}
|
||||
}
|
||||
|
||||
if (!numsockets)
|
||||
{
|
||||
@ -1751,7 +1749,7 @@ int newmain()
|
||||
# ifndef NO_LOG
|
||||
logstdout = 0;
|
||||
# endif // !NO_LOG
|
||||
}
|
||||
}
|
||||
|
||||
# endif // !defined(_WIN32) && !defined(NO_SOCKETS) && !defined(USE_MSRPC)
|
||||
|
||||
@ -1776,9 +1774,9 @@ int newmain()
|
||||
!IsNDR64Defined
|
||||
)
|
||||
{
|
||||
UseServerRpcNDR64 = !!KmsData->Flags & KMS_OPTIONS_USENDR64;
|
||||
UseServerRpcNDR64 = !!(KmsData->Flags & KMS_OPTIONS_USENDR64);
|
||||
# ifndef NO_RANDOM_EPID
|
||||
if (HostBuild&&RandomizationLevel)
|
||||
if (HostBuild && RandomizationLevel)
|
||||
{
|
||||
UseServerRpcNDR64 = HostBuild > 7601;
|
||||
}
|
||||
@ -1786,13 +1784,6 @@ int newmain()
|
||||
}
|
||||
# endif // !defined(USE_MSRPC) && !defined(SIMPLE_RPC)
|
||||
|
||||
# if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
|
||||
if (KmsData->MinorVer < 6)
|
||||
{
|
||||
printerrorf("Warning: Need database version 1.6 or greater to set custom ePids\n");
|
||||
}
|
||||
# endif // !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
|
||||
|
||||
# if !defined(NO_RANDOM_EPID) || !defined(NO_CL_PIDS) || !defined(NO_INI_FILE)
|
||||
KmsResponseParameters = (KmsResponseParam_t*)vlmcsd_malloc(sizeof(KmsResponseParam_t) * KmsData->CsvlkCount);
|
||||
memset(KmsResponseParameters, 0, sizeof(KmsResponseParam_t) * KmsData->CsvlkCount);
|
||||
@ -1805,7 +1796,7 @@ int newmain()
|
||||
for (opterr = 0; (o = getopt(global_argc, (char* const*)global_argv, (const char*)optstring)) > 0; ) switch (o)
|
||||
{
|
||||
case 'a':
|
||||
if (KmsData->MinorVer < 6 || !handleIniFileEpidParameter(optarg, FALSE, "command line"))
|
||||
if (!handleIniFileEpidParameter(optarg, FALSE, "command line"))
|
||||
{
|
||||
usage();
|
||||
}
|
||||
@ -1892,7 +1883,7 @@ int newmain()
|
||||
{
|
||||
printerrorf("Fatal: %s for %s failed: %s\n", "setuid", uname, strerror(errno));
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
# ifndef NO_SIGHUP
|
||||
}
|
||||
# endif // NO_SIGHUP
|
||||
@ -1905,6 +1896,22 @@ int newmain()
|
||||
// the lifetime of the process. So we generate them now
|
||||
# ifndef NO_RANDOM_EPID
|
||||
if (RandomizationLevel == 1) randomPidInit();
|
||||
# if !defined(NO_LOG) && !defined(NO_VERBOSE_LOG)
|
||||
if (logverbose)
|
||||
{
|
||||
int32_t i;
|
||||
|
||||
for (i = 0; i < KmsData->CsvlkCount; i++)
|
||||
{
|
||||
const CsvlkData_t* const csvlk = KmsData->CsvlkData + i;
|
||||
const char* csvlkIniName = getNextString(csvlk->EPid);
|
||||
const char* csvlkFullName = getNextString(csvlkIniName);
|
||||
csvlkFullName = *csvlkFullName ? csvlkFullName : "unknown";
|
||||
const char* ePid = KmsResponseParameters[i].Epid ? KmsResponseParameters[i].Epid : RandomizationLevel == 2 ? "" : csvlk->EPid;
|
||||
logger("Using CSVLK %s (%s) with %s ePID %s\n", csvlkIniName, csvlkFullName, (RandomizationLevel == 1 && KmsResponseParameters[i].IsRandom) || (RandomizationLevel == 2 && !KmsResponseParameters[i].Epid) ? "random" : "fixed", ePid);
|
||||
}
|
||||
}
|
||||
# endif // !defined(NO_LOG) && !defined(NO_VERBOSE_LOG)
|
||||
# endif
|
||||
|
||||
# if !defined(NO_SOCKETS)
|
||||
@ -1950,12 +1957,12 @@ int newmain()
|
||||
#if _MSC_VER && !defined(_DEBUG)&& !MULTI_CALL_BINARY
|
||||
int __stdcall WinStartUp(void)
|
||||
{
|
||||
WCHAR **szArgList;
|
||||
WCHAR** szArgList;
|
||||
int argc;
|
||||
szArgList = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
|
||||
int i;
|
||||
char **argv = (char**)vlmcsd_malloc(sizeof(char*)*argc);
|
||||
char** argv = (char**)vlmcsd_malloc(sizeof(char*) * argc);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ int server_main(int argc, CARGV argv);
|
||||
#define SA_NOCLDWAIT 0
|
||||
#endif
|
||||
|
||||
#ifndef NO_INI_FILE
|
||||
#if !defined(NO_INI_FILE) || !defined(NO_CL_PIDS)
|
||||
#define INI_PARAM_RANDOMIZATION_LEVEL 1
|
||||
#define INI_PARAM_LCID 2
|
||||
#define INI_PARAM_LISTEN 3
|
||||
|
28
src/wintap.c
28
src/wintap.c
@ -42,7 +42,7 @@ static BOOL isAddressAssigned()
|
||||
BOOL result = FALSE;
|
||||
|
||||
pIPAddrTable = (PMIB_IPADDRTABLE)vlmcsd_malloc(sizeof(MIB_IPADDRTABLE));
|
||||
DWORD status = GetIpAddrTable(pIPAddrTable, &dwSize, 0);
|
||||
const DWORD status = GetIpAddrTable(pIPAddrTable, &dwSize, 0);
|
||||
free(pIPAddrTable);
|
||||
|
||||
if (status != ERROR_INSUFFICIENT_BUFFER) return FALSE;
|
||||
@ -74,16 +74,16 @@ static BOOL isAddressAssigned()
|
||||
|
||||
static void parseTapArgument(char* argument)
|
||||
{
|
||||
char* equalsignPosition = strchr(argument, (int)'=');
|
||||
char* equalSignPosition = strchr(argument, (int)'=');
|
||||
char* slashPosition = strchr(argument, (int)'/');
|
||||
char* colonPosition = strchr(argument, (int)':');
|
||||
|
||||
szTapName = argument;
|
||||
|
||||
if (equalsignPosition)
|
||||
if (equalSignPosition)
|
||||
{
|
||||
*equalsignPosition = 0;
|
||||
szIpAddress = equalsignPosition + 1;
|
||||
*equalSignPosition = 0;
|
||||
szIpAddress = equalSignPosition + 1;
|
||||
}
|
||||
|
||||
if (slashPosition)
|
||||
@ -166,10 +166,10 @@ static HANDLE OpenTapHandle()
|
||||
WinErrorExit(regResult);
|
||||
}
|
||||
|
||||
char subkeyName[TAP_REGISTRY_DATA_SIZE];
|
||||
DWORD i, subKeySize = sizeof(subkeyName);
|
||||
char subKeyName[TAP_REGISTRY_DATA_SIZE];
|
||||
DWORD i, subKeySize = sizeof(subKeyName);
|
||||
|
||||
for (i = 0; (regResult = RegEnumKeyEx(regAdapterKey, i, subkeyName, &subKeySize, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS; i++)
|
||||
for (i = 0; (regResult = RegEnumKeyEx(regAdapterKey, i, subKeyName, &subKeySize, NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS; i++)
|
||||
{
|
||||
HKEY regSubKey;
|
||||
DWORD type, regDataSize;
|
||||
@ -177,7 +177,7 @@ static HANDLE OpenTapHandle()
|
||||
|
||||
if (regResult) WinErrorExit(regResult);
|
||||
|
||||
if ((regResult = RegOpenKeyEx(regAdapterKey, subkeyName, 0, KEY_READ | KEY_WOW64_64KEY, ®SubKey)) == ERROR_SUCCESS)
|
||||
if ((regResult = RegOpenKeyEx(regAdapterKey, subKeyName, 0, KEY_READ | KEY_WOW64_64KEY, ®SubKey)) == ERROR_SUCCESS)
|
||||
{
|
||||
regDataSize = sizeof(regData);
|
||||
|
||||
@ -201,8 +201,8 @@ static HANDLE OpenTapHandle()
|
||||
char connectionKeyName[TAP_REGISTRY_DATA_SIZE];
|
||||
|
||||
strncpy(connectionKeyName, NETWORK_CONNECTIONS_KEY "\\", sizeof(connectionKeyName));
|
||||
strncat(connectionKeyName, regData, sizeof(connectionKeyName));
|
||||
strncat(connectionKeyName, "\\Connection", sizeof(connectionKeyName));
|
||||
strncat(connectionKeyName, regData, sizeof(connectionKeyName) - strlen(connectionKeyName) - 1);
|
||||
strncat(connectionKeyName, "\\Connection", sizeof(connectionKeyName) - strlen(connectionKeyName) - 1);
|
||||
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, connectionKeyName, 0, KEY_READ | KEY_WOW64_64KEY, &connectionKey) == ERROR_SUCCESS)
|
||||
{
|
||||
@ -215,8 +215,8 @@ static HANDLE OpenTapHandle()
|
||||
{
|
||||
ActiveTapName = vlmcsd_strdup(deviceName);
|
||||
strncpy(deviceName, USERMODEDEVICEDIR, sizeof(deviceName));
|
||||
strncat(deviceName, regData, sizeof(deviceName));
|
||||
strncat(deviceName, strcmp(AdapterClass, "TEAMVIEWERVPN") ? TAP_WIN_SUFFIX : ".dgt", sizeof(deviceName));
|
||||
strncat(deviceName, regData, sizeof(deviceName) - strlen(deviceName) - 1);
|
||||
strncat(deviceName, strcmp(AdapterClass, "TEAMVIEWERVPN") ? TAP_WIN_SUFFIX : ".dgt", sizeof(deviceName) - strlen(deviceName) - 1);
|
||||
handle = CreateFile(deviceName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
|
||||
}
|
||||
}
|
||||
@ -231,7 +231,7 @@ static HANDLE OpenTapHandle()
|
||||
}
|
||||
|
||||
RegCloseKey(regSubKey);
|
||||
subKeySize = sizeof(subkeyName);
|
||||
subKeySize = sizeof(subKeyName);
|
||||
if (handle != INVALID_HANDLE_VALUE) break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user