// A stack version of SysAllocString #define DECL_STACK_BSTR(name, wideString) \ BSTR name = NULL; \ { \ UINT bytesReq = sizeof(wideString) + sizeof(UINT); \ UINT* temp = static_cast(_alloca(bytesReq)); \ *temp = bytesReq - sizeof(UINT); \ ++temp; \ wmemcpy((WCHAR*)temp, wideString, ARRAYSIZE(wideString)); \ name = (BSTR)temp; \ } #define DECL_STACK_BSTR_SIZE(name, size) \ BSTR name = NULL; \ { \ UINT bytesReq = size + sizeof(UINT); \ UINT* temp = static_cast(_alloca(bytesReq)); \ *temp = bytesReq - sizeof(UINT); \ ++temp; \ name = (BSTR)temp; \ } DECL_STACK_BSTR_SIZE(taskTime, sizeof("YYYY-MM-DDTHH:MM:SS+HH:MM")); // wmiStr is a date from WMI, such as Win32_OperatingSystem::LocalDateTime // task time needs to be from // DECL_STACK_BSTR_SIZE(taskTime, sizeof("YYYY-MM-DDTHH:MM:SS+HH:MM")); // or // SysAllocStringLen(NULL, sizeof("YYYY-MM-DDTHH:MM:SS+HH:MM")) // or any other bstr with at least 26 WCHARs / 52 bytes in size void WMITimeToTaskTime(BSTR wmiStr, BSTR taskTime) { // from YYYYMMDDHHMMSS.XXXXXX(+-)OOO // to YYYY-MM-DDTHH:MM:SS(+-)HH:MM WCHAR* startOfString = wmiStr; WCHAR* endOfString = startOfString + (sizeof("YYYYMMDDHHMMSS.MMMMMM+OOO") - 1); WCHAR* endOfMinutes = endOfString - 4; assert((*endOfMinutes) == L'+' || ((*endOfMinutes) == L'-')); // figure out the number of minutes used for time zone adjustment UINT minutes = 0; for(WCHAR* pEnd = endOfString - 1; pEnd != endOfMinutes; --pEnd) { minutes *= 10; minutes += (*pEnd - L'0'); } // turn it into hours and minutes UINT hours = minutes / 60; minutes %= 60; // build the hh:mm picture WCHAR timeInFormat[7]; timeInFormat[0] = *endOfMinutes; timeInFormat[3] = L':'; for(int i = 2; i >= 1; --i) { timeInFormat[i] = ((hours % 10) + L'0'); timeInFormat[i + 3] = ((minutes % 10) + L'0'); hours /= 10; minutes /= 10; } timeInFormat[6] = 0; WCHAR* years = taskTime; const int yearLen = 4; WCHAR* month = years + yearLen + 1; const int otherLen = 2; *(years + yearLen) = *(month + otherLen) = L'-'; WCHAR* days = month + otherLen + 1; *(days + otherLen) = L'T'; WCHAR* hoursStr = days + otherLen + 1; WCHAR* minutesStr = hoursStr + otherLen + 1; WCHAR* seconds = minutesStr + otherLen + 1; *(hoursStr + otherLen) = *(minutesStr + otherLen) = L':'; __movsw((USHORT*)seconds + otherLen, (USHORT*)timeInFormat, 7); WCHAR* wmiTimeStr = wmiStr; // copy years ULONGLONG* srcLL = (ULONGLONG*)wmiTimeStr, *dstLL = (ULONGLONG*)years; *dstLL = *srcLL; wmiTimeStr += yearLen; // copy months ULONG* srcUL = (ULONG*)wmiTimeStr, *dstUL = (ULONG*)month; *dstUL = *srcUL; ++srcUL; // copy days dstUL = (ULONG*)days; *dstUL = *srcUL; ++srcUL; // copy hours dstUL = (ULONG*)hoursStr; *dstUL = *srcUL; ++srcUL; // copy minutes dstUL = (ULONG*)minutesStr; *dstUL = *srcUL; ++srcUL; // copy seconds dstUL = (ULONG*)seconds; *dstUL = *srcUL; }