I try this simple code to calculate HDD write speed in my application:
#include <winternl.h>
...
float speed;
double divident;
PLARGE_INTEGER systime0, systime1;
LONGLONG elapsed_time;
...
write_flag = true ;
NtQuerySystemTime(systime0) ;
f_out->write(out_buffer0, chunk_len0);
f_out->write(out_buffer1, chunk_len1);
NtQuerySystemTime(systime1);
elapsed_time = systime1->QuadPart - systime0->QuadPart;
write_flag = false ;
divident = static_cast<double>(chunk_len0 + chunk_len1) / 1.048576 ; // 1.024 * 1.024 = 1.048576; divident yield value 1000000 times greater then value in MB
divident *= 10 ; // I want 'speed' to be in MB/s
speed = divident / static_cast<double>(elapsed_time) ;
...
but it fails to link.
On MSDN, the NtQuerySystemTime documentation says there is no associated import library and that I must use the LoadLibrary() and GetProcAddress() functions to dynamically link to Ntdll.dll. But I don't understand how to use those functions. Can someone please provide a code example of how to use those functions?
This is how you would be able to use this function.
HMODULE hNtDll = GetModuleHandleA("ntdll");
NTSTATUS (WINAPI *NtQuerySystemTime)(PLARGE_INTEGER) =
(NTSTATUS (WINAPI*)(PLARGE_INTEGER))GetProcAddress(hNtDll, "NtQuerySystemTime");
#include <stdio.h>
#include <windows.h>
typedef NTSYSAPI (CALLBACK *LPNTQUERYSYSTEMTIME)(PLARGE_INTEGER);
void main(void)
{
PLARGE_INTEGER SystemTime;
SystemTime = (PLARGE_INTEGER) malloc(sizeof(LARGE_INTEGER));
HMODULE hNtDll = GetModuleHandleA("ntdll");
LPNTQUERYSYSTEMTIME fnNtQuerySystemTime = (LPNTQUERYSYSTEMTIME)GetProcAddress(hNtDll, "NtQuerySystemTime");
if(fnNtQuerySystemTime){
printf("found NtQuerySystemTime function at ntdll.dll address:%p\n",fnNtQuerySystemTime);
fnNtQuerySystemTime(SystemTime);
printf("%llx\n", SystemTime->QuadPart);
}
free(SystemTime);
}
Related
I have the following Windows C++ code that I have adapted from:
https://alax.info/trac/public/browser/trunk/Utilities/MediaFoundation/VideoCaptureSynchronous/VideoCaptureSynchronous.cpp
More info about the original code:
https://alax.info/blog/1835
Thanks to Roman R!
#include <winsdkver.h>
#include <sdkddkver.h>
#include <stdio.h>
#include <tchar.h>
#include <mfapi.h>
#include <mfidl.h>
#include <mfreadwrite.h>
#include <atlbase.h>
#include <atlcom.h>
#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfreadwrite.lib")
#define __C ATLENSURE_SUCCEEDED
#define __D ATLENSURE_THROW
static UINT32 g_nIndex = 1;
int main()
{
__C(MFStartup(MF_VERSION));
{
CComPtr<IMFMediaSource> pMediaSource;
{
CComPtr<IMFAttributes> pAttributes;
__C(MFCreateAttributes(&pAttributes, 1));
__C(pAttributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID));
CComHeapPtr<IMFActivate*> ppActivates;
UINT32 nActivateCount = 0;
__C(MFEnumDeviceSources(pAttributes, &ppActivates, &nActivateCount));
__D(g_nIndex < nActivateCount, E_INVALIDARG);
const CComPtr<IMFActivate> pActivate = ppActivates[g_nIndex];
for (UINT32 nIndex = 0; nIndex < nActivateCount; nIndex++)
reinterpret_cast<CComPtr<IMFActivate>&>(ppActivates[nIndex]).Release();
__C(pActivate->ActivateObject(__uuidof(IMFMediaSource), (VOID**)&pMediaSource));
CComHeapPtr<WCHAR> pszFriendlyName;
__C(pActivate->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &pszFriendlyName, NULL));
_tprintf(_T("Friendly Name: %ls\n"), (LPCWSTR)pszFriendlyName);
}
CComPtr<IMFSourceReader> pSourceReader;
__C(MFCreateSourceReaderFromMediaSource(pMediaSource, NULL, &pSourceReader));
// Start My code
CComPtr<IMFMediaType> mediaType;
int index = 4;
__C(pSourceReader->GetNativeMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, index, &mediaType)); // returns MF_E_NO_MORE_TYPES if index is too large
__C(pSourceReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediaType));
// End my code
LONGLONG nBaseTime = 0;
for (; ; )
{
DWORD nStreamIndex;
DWORD nStreamFlags;
LONGLONG nTime;
CComPtr<IMFSample> pSample;
__C(pSourceReader->ReadSample(MF_SOURCE_READER_ANY_STREAM, 0, &nStreamIndex, &nStreamFlags, &nTime, &pSample));
nTime -= nBaseTime;
_tprintf(_T("nStreamIndex %d, nStreamFlags 0x%X, nTime %.3f, pSample 0x%p\n"), nStreamIndex, nStreamFlags, nTime / 1E7, (IMFSample*)pSample);
if (nStreamIndex == 0 && (nStreamFlags & MF_SOURCE_READERF_STREAMTICK))
{
ATLASSERT(!pSample);
nBaseTime = nTime;
continue;
}
}
}
__C(MFShutdown());
return 0;
}
My changes are within the Start my code/End my code block.
Without my changes the code runs fine.
With my changes however I only get one NULL sample from ReadSample() and after that it blocks
in ReadSample().
The output is:
Friendly Name: M034-WDR
nStreamIndex 0, nStreamFlags 0x100, nTime 65175.109, pSample 0x0000000000000000
I have listed the IMFMediaTypes supported by the camera with some other code and found that it had 8 different native formats out of which I preferred number 4.
How can I select this format and get this code to run?
I tried changing to
ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM,..)
but that did not help.
I'm trying to read export directory of a loaded module. The following program works as a 32-bit binary, but crashes as a 64-bit file.
All pointer is 64bit and I'm not sure the differences here, does anyone know what's wrong?
#include <windows.h>
#include <iostream>
#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
void PrintNames(HMODULE hModule)
{
DWORD dwExportsSize;
PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)ImageNtHeader(hModule);
PIMAGE_EXPORT_DIRECTORY ExportDirectory = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &dwExportsSize);
PULONG Names = (PULONG)((DWORD)hModule + ExportDirectory->AddressOfNames);
for (ULONG cEntry = 0; cEntry < ExportDirectory->NumberOfNames; cEntry++)
{
printf("%s\n", (char*)((DWORD_PTR)hModule + Names[cEntry]));
}
}
int main()
{
PrintNames(GetModuleHandleA("ntdll"));
return 0;
}
A DWORD is 32 bit and not enough for 64 bit. Change it to DWORD_PTR if you need pointer size
PULONG Names = (PULONG)((DWORD_PTR)hModule + ExportDirectory->AddressOfNames);
I have an existing project in Visual Studio, with a main file that calls a function file. I also created a CodeTimer.cpp following the steps from the Microsoft guide, and I placed it along with the necessary headers in the same directory as my code and function.
The issue is, I don't know how to link them. The solution builds fine, all three files combine with no errors. But when I CTRL-F5 it, I just see the output of my main, for obvious reasons (I didn't link the CodeTimer to the main).
This is my CodeTimer:
#include "stdafx.h"
#include <tchar.h>
#include <windows.h>
using namespace System;
int _tmain(int argc, _TCHAR* argv[])
{
__int64 ctr1 = 0, ctr2 = 0, freq = 0;
int acc = 0, i = 0;
// Start timing the code.
if (QueryPerformanceCounter((LARGE_INTEGER *)&ctr1) != 0)
{
// Code segment is being timed.
for (i = 0; i<100; i++) acc++;
// Finish timing the code.
QueryPerformanceCounter((LARGE_INTEGER *)&ctr2);
Console::WriteLine("Start Value: {0}", ctr1.ToString());
Console::WriteLine("End Value: {0}", ctr2.ToString());
QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
Console::WriteLine("QueryPerformanceFrequency : {0} per Seconds.", freq.ToString());
Console::WriteLine("QueryPerformanceCounter minimum resolution: 1/{0} Seconds.", freq.ToString());
Console::WriteLine("ctr2 - ctr1: {0} counts.", ((ctr2 - ctr1) * 1.0 / 1.0).ToString());
Console::WriteLine("65536 Increments by 1 computation time: {0} seconds.", ((ctr2 - ctr1) * 1.0 / freq).ToString());
}
else
{
DWORD dwError = GetLastError();
Console::WriteLine("Error value = {0}", dwError.ToString());
}
// Make the console window wait.
Console::WriteLine();
Console::Write("Press ENTER to finish.");
Console::Read();
return 0;
}
NVM fixed it. Just had to add the body of _tmain() in main() function under my code, and get ride of the CodeTimer.cpp file completely. It was a conflict of mains (multiple mains in one project, the compiler automatically outputted the one with the highest priority in the project).
I have a time in secs (ex:1505306792).
How to convert this into FILETIME?
Here is the code i have tried
INT64 timer64 = 1505306792;
timer64 = timer64 *1000 *10000;
ULONGLONG xx = timer64;
FILETIME fileTime;
ULARGE_INTEGER uliTime;
uliTime.QuadPart = xx;
fileTime.dwHighDateTime = uliTime.HighPart;
fileTime.dwLowDateTime = uliTime.LowPart;
This result FILETIME is coming as 1648-09-13 15:34:00
I am expecting this date to be 2017-09-13 12:46:31 . I am getting the same when using online converters.
Any idea how to solve this?
I have seen some answers using boost, but it is available in my project.
It's about adding 116444736000000000, see How To Convert a UNIX time_t to a Win32 FILETIME or SYSTEMTIME:
#include <winbase.h>
#include <winnt.h>
#include <time.h>
void UnixTimeToFileTime(time_t t, LPFILETIME pft)
{
// Note that LONGLONG is a 64-bit value
LONGLONG ll;
ll = Int32x32To64(t, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
In Java you can do this:
long now = (new Date()).getTime();
How can I do the same but in C++?
Because C++0x is awesome
namespace sc = std::chrono;
auto time = sc::system_clock::now(); // get the current time
auto since_epoch = time.time_since_epoch(); // get the duration since epoch
// I don't know what system_clock returns
// I think it's uint64_t nanoseconds since epoch
// Either way this duration_cast will do the right thing
auto millis = sc::duration_cast<sc::milliseconds>(since_epoch);
long now = millis.count(); // just like java (new Date()).getTime();
This works with gcc 4.4+. Compile it with --std=c++0x. I don't know if VS2010 implements std::chrono yet.
There is no such method in standard C++ (in standard C++, there is only second-accuracy, not millisecond). You can do it in non-portable ways, but since you didn't specify I will assume that you want a portable solution. Your best bet, I would say, is the boost function microsec_clock::local_time().
I like to have a function called time_ms defined as such:
// Used to measure intervals and absolute times
typedef int64_t msec_t;
// Get current time in milliseconds from the Epoch (Unix)
// or the time the system started (Windows).
msec_t time_ms(void);
The implementation below should work in Windows as well as Unix-like systems.
#if defined(__WIN32__)
#include <windows.h>
msec_t time_ms(void)
{
return timeGetTime();
}
#else
#include <sys/time.h>
msec_t time_ms(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (msec_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
#endif
Note that the time returned by the Windows branch is milliseconds since the system started, while the time returned by the Unix branch is milliseconds since 1970. Thus, if you use this code, only rely on differences between times, not the absolute time itself.
You can try this code (get from StockFish chess engine source code (GPL)):
#include <iostream>
#include <stdio>
#if !defined(_WIN32) && !defined(_WIN64) // Linux - Unix
# include <sys/time.h>
typedef timeval sys_time_t;
inline void system_time(sys_time_t* t) {
gettimeofday(t, NULL);
}
inline long long time_to_msec(const sys_time_t& t) {
return t.tv_sec * 1000LL + t.tv_usec / 1000;
}
#else // Windows and MinGW
# include <sys/timeb.h>
typedef _timeb sys_time_t;
inline void system_time(sys_time_t* t) { _ftime(t); }
inline long long time_to_msec(const sys_time_t& t) {
return t.time * 1000LL + t.millitm;
}
#endif
int main() {
sys_time_t t;
system_time(&t);
long long currentTimeMs = time_to_msec(t);
std::cout << "currentTimeMs:" << currentTimeMs << std::endl;
getchar(); // wait for keyboard input
}
Standard C++ does not have a time function with subsecond precision.
However, almost every operating system does. So you have to write code that is OS-dependent.
Win32:
GetSystemTime()
GetSystemTimeAsFileTime()
Unix/POSIX:
gettimeofday()
clock_gettime()
Boost has a useful library for doing this:
http://www.boost.org/doc/libs/1_43_0/doc/html/date_time.html
ptime microsec_clock::local_time() or ptime second_clock::local_time()
Java:
package com.company;
public class Main {
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
}
}
c++:
#include <stdio.h>
#include <windows.h>
__int64 currentTimeMillis() {
FILETIME f;
GetSystemTimeAsFileTime(&f);
(long long)f.dwHighDateTime;
__int64 nano = ((__int64)f.dwHighDateTime << 32LL) + (__int64)f.dwLowDateTime;
return (nano - 116444736000000000LL) / 10000;
}
int main() {
printf("%lli\n ", currentTimeMillis());
return 0;
}