Different CRC32 checksum for the same file - c++

Basically, I have an application which imports a few DLLs and some Python libraries.
I did another application which calculates CRC32 for each of these files and I've added the list on my main application because I want to make it to check these files.
The problem is that sometimes the main application detects a DLL or a library modified even if it wasn't. It don't happens everytime and I am wondering why does that happens? What can determine the CRC32 checksum to differ? It's because my application loads these DLLs or is something external like viruses or anything else?
Here's the code for both main application and the application which does the CRC32 list:
#include "boost/crc.hpp"
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include "boost/progress.hpp"
#include "boost/integer.hpp"
using namespace std;
namespace fs = boost::filesystem;
int CheckCRC32(LPCSTR szFileName, DWORD dwCRC32)
{
if (!fs::exists(szFileName))
return 1;
DWORD dwResult = 0;
boost::crc_32_type result;
std::streamsize const buffer_size = 1024;
ifstream file(szFileName, std::ios_base::binary);
if (file)
{
do
{
char buffer[buffer_size];
file.read(buffer, buffer_size);
result.process_bytes(buffer, file.gcount());
} while(file);
}
else
return 1;
dwResult = result.checksum();
if (dwResult <= 0)
return 1;
if (dwResult != dwCRC32)
return 2;
return 0;
}
Also, if you have another solution for doing such things or if you have a solution for this method, please let me know.

I am not really trusting your 1024 bytes fixed buffer and the order of calls you chose. Either it is your intention to only use the first 1024 bytes of your files for the crc or this could already be the problem. On the other hand, if the files you crc are smaller than those 1024, it is up to the behavior of file.read() what happens.
Just to give you an option, here the code for a "low level" alternative. If the same crc values will be obtained with this version will depend on whether my initial crc value of 0 is "by the book" or if you need to use another start value.
#include <Windows.h>
#include <cstdint>
#include <string>
#include <vector>
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32_t
crc32(uint32_t crc, const void *buf, size_t size)
{
const uint8_t *p = static_cast<const uint8_t*>(buf);
crc = crc ^ ~0U;
while (size--)
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
return crc ^ ~0U;
}
bool Crc32OfFile(const char * pathToFile, uint32_t &result)
{
bool success = false;
HANDLE hFile =
::CreateFileA
( pathToFile
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN
, NULL
);
if (INVALID_HANDLE_VALUE != hFile)
{
DWORD fileSize = ::GetFileSize(hFile, NULL);
std::vector<uint8_t> buffer;
buffer.resize(fileSize);
DWORD bytesRead = 0UL;
if (::ReadFile(hFile, &buffer[0], buffer.size(), &bytesRead, NULL))
{
if (bytesRead == fileSize)
{
result = crc32(0UL, &buffer[0], buffer.size());
success = true;
}
}
::CloseHandle(hFile);
}
return success;
}

Related

Enumerating modules cannot deallocate the allocated space and duplicate module names

I'm enumerating all DLL modules in a process, but there are two issues:
#1 Duplicate records
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume4\AC\Debug\AC.exe
\Device\HarddiskVolume2\Windows\SysWOW64\KernelBase.dll
\Device\HarddiskVolume2\Windows\SysWOW64\KernelBase.dll
\Device\HarddiskVolume2\Windows\SysWOW64\KernelBase.dll
\Device\HarddiskVolume2\Windows\SysWOW64\KernelBase.dll
\Device\HarddiskVolume2\Windows\SysWOW64\KernelBase.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\SysWOW64\kernel32.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\System32\wow64cpu.dll
\Device\HarddiskVolume2\Windows\SysWOW64\ntdll.dll
\Device\HarddiskVolume2\Windows\SysWOW64\ntdll.dll
\Device\HarddiskVolume2\Windows\SysWOW64\ntdll.dll
\Device\HarddiskVolume2\Windows\SysWOW64\ntdll.dll
#2 NtFreeVirtualMemory doesn't deallocate the whole space it allocated.
Before NtFreeVirtualMemory call
After it. You can see how it left all those regions.
Code
bool enumerate_modules()
{
MEMORY_BASIC_INFORMATION mbi{};
const std::size_t buffer_size = 512;
void* base_address = 0;
std::size_t region_size = buffer_size;
NTSTATUS status = NtAllocateVirtualMemory(NtCurrentProcess(), &base_address, 0, &region_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE));
if (!NT_SUCCESS(status))
return false;
const auto& section_name = reinterpret_cast<PMEMORY_SECTION_NAME>(base_address);
SYSTEM_INFO si{};
GetSystemInfo(&si);
auto* min_address = static_cast<std::uint8_t*>(si.lpMinimumApplicationAddress);
auto* max_address = static_cast<std::uint8_t*>(si.lpMaximumApplicationAddress);
while (min_address < max_address)
{
status = NtQueryVirtualMemory(NtCurrentProcess(), min_address, MemoryBasicInformation, &mbi, sizeof mbi, nullptr);
if (!NT_SUCCESS(status))
break;
if (mbi.Type == MEM_IMAGE)
{
status = NtQueryVirtualMemory(NtCurrentProcess(), min_address, MemoryMappedFilenameInformation, section_name, buffer_size, nullptr);
if (!NT_SUCCESS(status))
break;
const auto& dll = section_name->SectionFileName.Buffer;
printf("%S\n", dll);
}
min_address += mbi.RegionSize;
}
region_size = 0;
status = NtFreeVirtualMemory(NtCurrentProcess(), &base_address, &region_size, MEM_RELEASE);
if (!NT_SUCCESS(status))
return false;
return true;
}
"I'm enumerating all DLL modules in a process"
Well, you're not. That's what EnumProcessModules does. You enumerate memory regions.
As for the remaining pages; you didn't DECOMMIT them.
Note that these Nt functions are very low-level and assume that you know exactly what you are doing.

lein repl and any command with "lein" Doesn't Work

I have just started learning Clojure from Daniel Higginbottam's book called Clojure for the Brave and True. Needless to say, you need Leiningen and Cider for a good Clojure workflow.
Before I have tried installing cider to emacs, my Leiningen was working fine but somehow after I have tingled some settings with emacs (installing cider), my Leiningen installation started to give stack trace errors such as below: (I don't know how can this happen at all)
How can I fix this?
(Also, I have tried re-installing Leiningen, which didn't solve the issue.)
Java HotSpot(TM) 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
clojure.lang.Compiler$CompilerException: Syntax error compiling at (cider/nrepl.clj:1:1).
#:clojure.error{:phase :compile-syntax-check, :line 1, :column 1, :source "cider/nrepl.clj"}
at clojure.lang.Compiler.load (Compiler.java:7648)
clojure.lang.RT.loadResourceScript (RT.java:381)
clojure.lang.RT.loadResourceScript (RT.java:372)
clojure.lang.RT.load (RT.java:459)
clojure.lang.RT.load (RT.java:424)
clojure.core$load$fn__6839.invoke (core.clj:6126)
clojure.core$load.invokeStatic (core.clj:6125)
clojure.core$load.doInvoke (core.clj:6109)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.core$load_one.invokeStatic (core.clj:5908)
clojure.core$load_one.invoke (core.clj:5903)
clojure.core$load_lib$fn__6780.invoke (core.clj:5948)
clojure.core$load_lib.invokeStatic (core.clj:5947)
clojure.core$load_lib.doInvoke (core.clj:5928)
clojure.lang.RestFn.applyTo (RestFn.java:142)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$load_libs.invokeStatic (core.clj:5985)
clojure.core$load_libs.doInvoke (core.clj:5969)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$require.invokeStatic (core.clj:6007)
clojure.core$require.doInvoke (core.clj:6007)
clojure.lang.RestFn.invoke (RestFn.java:421)
cider_nrepl.plugin$eval659$loading__6721__auto____660.invoke (plugin.clj:1)
cider_nrepl.plugin$eval659.invokeStatic (plugin.clj:1)
cider_nrepl.plugin$eval659.invoke (plugin.clj:1)
clojure.lang.Compiler.eval (Compiler.java:7177)
clojure.lang.Compiler.eval (Compiler.java:7166)
clojure.lang.Compiler.load (Compiler.java:7636)
clojure.lang.RT.loadResourceScript (RT.java:381)
clojure.lang.RT.loadResourceScript (RT.java:372)
clojure.lang.RT.load (RT.java:459)
clojure.lang.RT.load (RT.java:424)
clojure.core$load$fn__6839.invoke (core.clj:6126)
clojure.core$load.invokeStatic (core.clj:6125)
clojure.core$load.doInvoke (core.clj:6109)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.core$load_one.invokeStatic (core.clj:5908)
clojure.core$load_one.invoke (core.clj:5903)
clojure.core$load_lib$fn__6780.invoke (core.clj:5948)
clojure.core$load_lib.invokeStatic (core.clj:5947)
clojure.core$load_lib.doInvoke (core.clj:5928)
clojure.lang.RestFn.applyTo (RestFn.java:142)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$load_libs.invokeStatic (core.clj:5985)
clojure.core$load_libs.doInvoke (core.clj:5969)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$require.invokeStatic (core.clj:6007)
clojure.core$require.doInvoke (core.clj:6007)
clojure.lang.RestFn.invoke (RestFn.java:408)
leiningen.core.utils$require_resolve.invokeStatic (utils.clj:102)
leiningen.core.utils$require_resolve.invoke (utils.clj:95)
leiningen.core.project$apply_middleware.invokeStatic (project.clj:850)
leiningen.core.project$apply_middleware.invoke (project.clj:843)
clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
clojure.core.protocols$fn__8154.invokeStatic (protocols.clj:136)
clojure.core.protocols/fn (protocols.clj:124)
clojure.core.protocols$fn__8114$G__8109__8123.invoke (protocols.clj:19)
clojure.core.protocols$seq_reduce.invokeStatic (protocols.clj:31)
clojure.core.protocols$fn__8146.invokeStatic (protocols.clj:75)
clojure.core.protocols/fn (protocols.clj:75)
clojure.core.protocols$fn__8088$G__8083__8101.invoke (protocols.clj:13)
clojure.core$reduce.invokeStatic (core.clj:6828)
clojure.core$reduce.invoke (core.clj:6810)
leiningen.core.project$apply_middleware.invokeStatic (project.clj:845)
leiningen.core.project$apply_middleware.invoke (project.clj:843)
leiningen.core.project$activate_middleware.invokeStatic (project.clj:877)
leiningen.core.project$activate_middleware.invoke (project.clj:873)
leiningen.core.project$set_profiles.invokeStatic (project.clj:966)
leiningen.core.project$set_profiles.doInvoke (project.clj:959)
clojure.lang.RestFn.invoke (RestFn.java:425)
leiningen.core.project$init_project.invokeStatic (project.clj:1041)
leiningen.core.project$init_project.invoke (project.clj:1016)
leiningen.core.project$init_project.invokeStatic (project.clj:1042)
leiningen.core.project$init_project.invoke (project.clj:1016)
leiningen.core.main$default_project.invokeStatic (main.clj:419)
leiningen.core.main$default_project.invoke (main.clj:412)
leiningen.core.main$_main$fn__7419.invoke (main.clj:449)
leiningen.core.main$_main.invokeStatic (main.clj:442)
leiningen.core.main$_main.doInvoke (main.clj:439)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.lang.Var.applyTo (Var.java:705)
clojure.core$apply.invokeStatic (core.clj:665)
clojure.main$main_opt.invokeStatic (main.clj:514)
clojure.main$main_opt.invoke (main.clj:510)
clojure.main$main.invokeStatic (main.clj:664)
clojure.main$main.doInvoke (main.clj:616)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.lang.Var.applyTo (Var.java:705)
clojure.main.main (main.java:40)
Caused by: java.io.FileNotFoundException: Could not locate clojure/tools/nrepl/server__init.class, clojure/tools/nrepl/server.clj or clojure/tools/nrepl/server.cljc on classpath.
at clojure.lang.RT.load (RT.java:462)
clojure.lang.RT.load (RT.java:424)
clojure.core$load$fn__6839.invoke (core.clj:6126)
clojure.core$load.invokeStatic (core.clj:6125)
clojure.core$load.doInvoke (core.clj:6109)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.core$load_one.invokeStatic (core.clj:5908)
clojure.core$load_one.invoke (core.clj:5903)
clojure.core$load_lib$fn__6780.invoke (core.clj:5948)
clojure.core$load_lib.invokeStatic (core.clj:5947)
clojure.core$load_lib.doInvoke (core.clj:5928)
clojure.lang.RestFn.applyTo (RestFn.java:142)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$load_libs.invokeStatic (core.clj:5985)
clojure.core$load_libs.doInvoke (core.clj:5969)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$require.invokeStatic (core.clj:6007)
clojure.core$require.doInvoke (core.clj:6007)
clojure.lang.RestFn.invoke (RestFn.java:1289)
cider.nrepl$eval665$loading__6721__auto____666.invoke (nrepl.clj:1)
cider.nrepl$eval665.invokeStatic (nrepl.clj:1)
cider.nrepl$eval665.invoke (nrepl.clj:1)
clojure.lang.Compiler.eval (Compiler.java:7177)
clojure.lang.Compiler.eval (Compiler.java:7166)
clojure.lang.Compiler.load (Compiler.java:7636)
clojure.lang.RT.loadResourceScript (RT.java:381)
clojure.lang.RT.loadResourceScript (RT.java:372)
clojure.lang.RT.load (RT.java:459)
clojure.lang.RT.load (RT.java:424)
clojure.core$load$fn__6839.invoke (core.clj:6126)
clojure.core$load.invokeStatic (core.clj:6125)
clojure.core$load.doInvoke (core.clj:6109)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.core$load_one.invokeStatic (core.clj:5908)
clojure.core$load_one.invoke (core.clj:5903)
clojure.core$load_lib$fn__6780.invoke (core.clj:5948)
clojure.core$load_lib.invokeStatic (core.clj:5947)
clojure.core$load_lib.doInvoke (core.clj:5928)
clojure.lang.RestFn.applyTo (RestFn.java:142)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$load_libs.invokeStatic (core.clj:5985)
clojure.core$load_libs.doInvoke (core.clj:5969)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$require.invokeStatic (core.clj:6007)
clojure.core$require.doInvoke (core.clj:6007)
clojure.lang.RestFn.invoke (RestFn.java:421)
cider_nrepl.plugin$eval659$loading__6721__auto____660.invoke (plugin.clj:1)
cider_nrepl.plugin$eval659.invokeStatic (plugin.clj:1)
cider_nrepl.plugin$eval659.invoke (plugin.clj:1)
clojure.lang.Compiler.eval (Compiler.java:7177)
clojure.lang.Compiler.eval (Compiler.java:7166)
clojure.lang.Compiler.load (Compiler.java:7636)
clojure.lang.RT.loadResourceScript (RT.java:381)
clojure.lang.RT.loadResourceScript (RT.java:372)
clojure.lang.RT.load (RT.java:459)
clojure.lang.RT.load (RT.java:424)
clojure.core$load$fn__6839.invoke (core.clj:6126)
clojure.core$load.invokeStatic (core.clj:6125)
clojure.core$load.doInvoke (core.clj:6109)
clojure.lang.RestFn.invoke (RestFn.java:408)
clojure.core$load_one.invokeStatic (core.clj:5908)
clojure.core$load_one.invoke (core.clj:5903)
clojure.core$load_lib$fn__6780.invoke (core.clj:5948)
clojure.core$load_lib.invokeStatic (core.clj:5947)
clojure.core$load_lib.doInvoke (core.clj:5928)
clojure.lang.RestFn.applyTo (RestFn.java:142)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$load_libs.invokeStatic (core.clj:5985)
clojure.core$load_libs.doInvoke (core.clj:5969)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.core$apply.invokeStatic (core.clj:667)
clojure.core$require.invokeStatic (core.clj:6007)
clojure.core$require.doInvoke (core.clj:6007)
clojure.lang.RestFn.invoke (RestFn.java:408)
leiningen.core.utils$require_resolve.invokeStatic (utils.clj:102)
leiningen.core.utils$require_resolve.invoke (utils.clj:95)
leiningen.core.project$apply_middleware.invokeStatic (project.clj:850)
leiningen.core.project$apply_middleware.invoke (project.clj:843)
clojure.lang.ArrayChunk.reduce (ArrayChunk.java:58)
clojure.core.protocols$fn__8154.invokeStatic (protocols.clj:136)
clojure.core.protocols/fn (protocols.clj:124)
clojure.core.protocols$fn__8114$G__8109__8123.invoke (protocols.clj:19)
clojure.core.protocols$seq_reduce.invokeStatic (protocols.clj:31)
clojure.core.protocols$fn__8146.invokeStatic (protocols.clj:75)
clojure.core.protocols/fn (protocols.clj:75)
clojure.core.protocols$fn__8088$G__8083__8101.invoke (protocols.clj:13)
clojure.core$reduce.invokeStatic (core.clj:6828)
clojure.core$reduce.invoke (core.clj:6810)
leiningen.core.project$apply_middleware.invokeStatic (project.clj:845)
leiningen.core.project$apply_middleware.invoke (project.clj:843)
leiningen.core.project$activate_middleware.invokeStatic (project.clj:877)
leiningen.core.project$activate_middleware.invoke (project.clj:873)
leiningen.core.project$set_profiles.invokeStatic (project.clj:966)
leiningen.core.project$set_profiles.doInvoke (project.clj:959)
clojure.lang.RestFn.invoke (RestFn.java:425)
leiningen.core.project$init_project.invokeStatic (project.clj:1041)
leiningen.core.project$init_project.invoke (project.clj:1016)
leiningen.core.project$init_project.invokeStatic (project.clj:1042)
leiningen.core.project$init_project.invoke (project.clj:1016)
leiningen.core.main$default_project.invokeStatic (main.clj:419)
leiningen.core.main$default_project.invoke (main.clj:412)
leiningen.core.main$_main$fn__7419.invoke (main.clj:449)
leiningen.core.main$_main.invokeStatic (main.clj:442)
leiningen.core.main$_main.doInvoke (main.clj:439)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.lang.Var.applyTo (Var.java:705)
clojure.core$apply.invokeStatic (core.clj:665)
clojure.main$main_opt.invokeStatic (main.clj:514)
clojure.main$main_opt.invoke (main.clj:510)
clojure.main$main.invokeStatic (main.clj:664)
clojure.main$main.doInvoke (main.clj:616)
clojure.lang.RestFn.applyTo (RestFn.java:137)
clojure.lang.Var.applyTo (Var.java:705)
clojure.main.main (main.java:40)

MP4 Created Using FFmpeg API Can't Be Played in Media Players

I've been struggling with this issue for days. There are similar issues posted here and around the web, but none of the solutions seem to work for me. They are possibly outdated?
Here is the current iteration of code I'm using to generate the MP4 file.
It generates a simple 2 second .mp4 file that fails to play in any player I've tried. If I run that mp4 file back through the FFmpeg command line, it will generate a perfectly playable movie out of it. So the data is there.
Also, if you modify the output file name in this code from .mp4 to .avi, this code generates a playable avi file too. So whatever it is, it is tied to the H.264 format.
I'm sure I'm missing something simple, but for the life of me, I can't figure out what that is.
Any help would be greatly appreciated!
Here is a link to the VC++ project. MovieMaker.zip
MovieMaker.h
#pragma once
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/opt.h>
}
class FMovieMaker
{
public:
~FMovieMaker();
bool Initialize(const char* FileName, int Width = 1920, int Height = 1080, int FPS = 30, int BitRate = 2000);
bool RecordFrame(uint8_t* BGRAData);
bool Finalize();
bool IsInitialized() const { return bInitialized; }
int GetWidth() const { return CodecContext ? CodecContext->width : 0; }
int GetHeight() const { return CodecContext ? CodecContext->height : 0; }
private:
bool EncodeFrame(bool bFinalize);
void Log(const char* fmt, ...);
AVOutputFormat* OutputFormat = nullptr;
AVFormatContext* FormatContext = nullptr;
AVCodecContext* CodecContext = nullptr;
AVFrame* Frame = nullptr;
SwsContext* ColorConverter = nullptr;
int64_t RecordedFrames = 0;
bool bInitialized = false;
};
MovieMaker.cpp
#include "MovieMaker.h"
FMovieMaker::~FMovieMaker()
{
if (IsInitialized())
Finalize();
}
bool FMovieMaker::Initialize(const char* FileName, int Width /*= 1920*/, int Height /*= 1080*/, int FPS /*= 30*/, int BitRate /*= 2000*/)
{
OutputFormat = av_guess_format(nullptr, FileName, nullptr);
if (!OutputFormat)
{
Log("Couldn't guess the output format from the filename: %s", FileName);
return false;
}
AVCodecID CodecID = OutputFormat->video_codec;
if (CodecID == AV_CODEC_ID_NONE)
{
Log("Could not determine a codec to use");
return false;
}
/* allocate the output media context */
int ErrorCode = avformat_alloc_output_context2(&FormatContext, OutputFormat, nullptr, FileName);
if (ErrorCode < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Failed to allocate format context: %s", Error);
return false;
}
else if (!FormatContext)
{
Log("Failed to get format from filename: %s", FileName);
return false;
}
/* find the video encoder */
const AVCodec* Codec = avcodec_find_encoder(CodecID);
if (!Codec)
{
Log("Codec '%d' not found", CodecID);
return false;
}
/* create the video stream */
AVStream* Stream = avformat_new_stream(FormatContext, Codec);
if (!Stream)
{
Log("Failed to allocate stream");
return false;
}
/* create the codec context */
CodecContext = avcodec_alloc_context3(Codec);
if (!CodecContext)
{
Log("Could not allocate video codec context");
return false;
}
Stream->codecpar->codec_id = OutputFormat->video_codec;
Stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
Stream->codecpar->width = Width;
Stream->codecpar->height = Height;
Stream->codecpar->format = AV_PIX_FMT_YUV420P;
Stream->codecpar->bit_rate = (int64_t)BitRate * 1000;
avcodec_parameters_to_context(CodecContext, Stream->codecpar);
CodecContext->time_base = { 1, FPS };
CodecContext->max_b_frames = 2;
CodecContext->gop_size = 12;
CodecContext->framerate = { FPS, 1 };
if (Stream->codecpar->codec_id == AV_CODEC_ID_H264)
av_opt_set(CodecContext, "preset", "medium", 0);
else if (Stream->codecpar->codec_id == AV_CODEC_ID_H265)
av_opt_set(CodecContext, "preset", "medium", 0);
avcodec_parameters_from_context(Stream->codecpar, CodecContext);
if (FormatContext->oformat->flags & AVFMT_GLOBALHEADER)
CodecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
if ((ErrorCode = avcodec_open2(CodecContext, Codec, NULL)) < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Failed to open codec: %s", Error);
return false;
}
if (!(OutputFormat->flags & AVFMT_NOFILE))
{
if ((ErrorCode = avio_open(&FormatContext->pb, FileName, AVIO_FLAG_WRITE)) < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Failed to open file: %s", Error);
return false;
}
}
Stream->time_base = CodecContext->time_base;
if ((ErrorCode = avformat_write_header(FormatContext, NULL)) < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Failed to write header: %s", Error);
return false;
}
CodecContext->time_base = Stream->time_base;
av_dump_format(FormatContext, 0, FileName, 1);
// create the frame
{
Frame = av_frame_alloc();
if (!Frame)
{
Log("Could not allocate video frame");
return false;
}
Frame->format = CodecContext->pix_fmt;
Frame->width = CodecContext->width;
Frame->height = CodecContext->height;
ErrorCode = av_frame_get_buffer(Frame, 32);
if (ErrorCode < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Could not allocate the video frame data: %s", Error);
return false;
}
}
// create a color converter
{
ColorConverter = sws_getContext(CodecContext->width, CodecContext->height, AV_PIX_FMT_BGRA,
CodecContext->width, CodecContext->height, AV_PIX_FMT_YUV420P, 0, 0, 0, 0);
if (!ColorConverter)
{
Log("Could not allocate color converter");
return false;
}
}
bInitialized = true;
return true;
}
bool FMovieMaker::RecordFrame(uint8_t* BGRAData)
{
if (!bInitialized)
{
Log("Cannot record frames on an uninitialized Video Recorder");
return false;
}
/*make sure the frame data is writable */
int ErrorCode = av_frame_make_writable(Frame);
if (ErrorCode < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Could not make the frame writable: %s", Error);
return false;
}
/* convert the bgra bitmap data into yuv frame data */
int inLinesize[1] = { 4 * CodecContext->width }; // RGB stride
sws_scale(ColorConverter, &BGRAData, inLinesize, 0, CodecContext->height, Frame->data, Frame->linesize);
//Frame->pts = RecordedFrames++;
Frame->pts = CodecContext->time_base.den / CodecContext->time_base.num * CodecContext->framerate.den / CodecContext->framerate.num * (RecordedFrames++);
//The following assumes that codecContext->time_base = (AVRational){1, 1};
//Frame->pts = frameduration * (RecordedFrames++) * Stream->time_base.den / (Stream->time_base.num * fps);
//Frame->pts += av_rescale_q(1, CodecContext->time_base, Stream->time_base);
return EncodeFrame(false);
}
bool FMovieMaker::EncodeFrame(bool bFinalize)
{
/* send the frame to the encoder */
int ErrorCode = avcodec_send_frame(CodecContext, bFinalize ? nullptr : Frame);
if (ErrorCode < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Error sending a frame for encoding: %s", Error);
return false;
}
AVPacket Packet;
av_init_packet(&Packet);
Packet.data = NULL;
Packet.size = 0;
Packet.flags |= AV_PKT_FLAG_KEY;
Packet.pts = Frame->pts;
if (avcodec_receive_packet(CodecContext, &Packet) == 0)
{
//std::cout << "pkt key: " << (Packet.flags & AV_PKT_FLAG_KEY) << " " << Packet.size << " " << (counter++) << std::endl;
uint8_t* size = ((uint8_t*)Packet.data);
//std::cout << "first: " << (int)size[0] << " " << (int)size[1] << " " << (int)size[2] << " " << (int)size[3] << " " << (int)size[4] << " " << (int)size[5] << " " << (int)size[6] << " " << (int)size[7] << std::endl;
av_interleaved_write_frame(FormatContext, &Packet);
av_packet_unref(&Packet);
}
return true;
}
bool FMovieMaker::Finalize()
{
if (!bInitialized)
{
Log("Cannot finalize uninitialized Video Recorder");
return false;
}
//DELAYED FRAMES
AVPacket Packet;
av_init_packet(&Packet);
Packet.data = NULL;
Packet.size = 0;
for (;;)
{
avcodec_send_frame(CodecContext, NULL);
if (avcodec_receive_packet(CodecContext, &Packet) == 0)
{
av_interleaved_write_frame(FormatContext, &Packet);
av_packet_unref(&Packet);
}
else
break;
}
av_write_trailer(FormatContext);
if (!(OutputFormat->flags & AVFMT_NOFILE))
{
int ErrorCode = avio_close(FormatContext->pb);
if (ErrorCode < 0)
{
char Error[AV_ERROR_MAX_STRING_SIZE];
av_make_error_string(Error, AV_ERROR_MAX_STRING_SIZE, ErrorCode);
Log("Failed to close file: %s", Error);
}
}
if (Frame)
{
av_frame_free(&Frame);
Frame = nullptr;
}
if (CodecContext)
{
avcodec_free_context(&CodecContext);
CodecContext = nullptr;
}
if (FormatContext)
{
avformat_free_context(FormatContext);
FormatContext = nullptr;
}
if (ColorConverter)
{
sws_freeContext(ColorConverter);
ColorConverter = nullptr;
}
bInitialized = false;
return true;
}
void FMovieMaker::Log(const char* fmt, ...)
{
va_list args;
fprintf(stderr, "LOG: ");
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fprintf(stderr, "\n");
}
Main.cpp
#include "MovieMaker.h"
uint8_t FtoB(float x)
{
if (x <= 0.0f)
return 0;
if (x >= 1.0f)
return 255;
else
return (uint8_t)(x * 255.0f);
}
void SetPixelColor(float X, float Y, float Width, float Height, float t, uint8_t* BGRA)
{
t += 12.0f; // more interesting colors at this time
float P[2] = { 0.1f * X - 25.0f, 0.1f * Y - 25.0f };
float V = sqrtf(P[0] * P[0] + P[1] * P[1]);
BGRA[0] = FtoB(sinf(V + t / 0.78f));
BGRA[1] = FtoB(sinf(V + t / 10.0f));
BGRA[2] = FtoB(sinf(V + t / 36e2f));
BGRA[3] = 255;
}
int main()
{
FMovieMaker MovieMaker;
const char* FileName = "C:\\ffmpeg\\MyMovieMakerMovie.mp4";
int Width = 640;
int Height = 480;
int FPS = 30;
int BitRateKBS = 2000;
if (MovieMaker.Initialize(FileName, Width, Height, FPS, BitRateKBS))
{
int Size = Width * 4 * Height;
uint8_t* BGRAData = new uint8_t[Size];
memset(BGRAData, 255, Size);
for (float Frame = 0; Frame < 60; Frame++)
{
// fill the image data with something interesting
for (float Y = 0; Y < Height; Y++)
{
for (float X = 0; X < Width; X++)
{
SetPixelColor(X, Y, (float)Width, (float)Height, Frame / (float)FPS, &BGRAData[(int)(Y * Width + X) * 4]);
}
}
if (!MovieMaker.RecordFrame(BGRAData))
break;
}
delete[] BGRAData;
MovieMaker.Finalize();
}
}
If I have the lines that add the AV_CODEC_FLAG_GLOBAL_HEADER flag like shown above, I get all sorts of issues in the output from ffprobe MyMovieMakerMovie.mp4.
C:\ffmpeg>ffprobe MyMovieMakerMovie.mp4
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20200122
configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
[h264 # 000001d44b795b00] non-existing PPS 0 referenced
[h264 # 000001d44b795b00] decode_slice_header error
[h264 # 000001d44b795b00] no frame!
...
[h264 # 000001d44b795b00] non-existing PPS 0 referenced
[h264 # 000001d44b795b00] decode_slice_header error
[h264 # 000001d44b795b00] no frame!
[mov,mp4,m4a,3gp,3g2,mj2 # 000001d44b783880] decoding for stream 0 failed
[mov,mp4,m4a,3gp,3g2,mj2 # 000001d44b783880] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 640x480, 20528 kb/s): unspecified pixel format
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'MyMovieMakerMovie.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:01.97, start: 0.000000, bitrate: 20529 kb/s
Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 640x480, 20528 kb/s, 30.51 fps, 30 tbr, 15360 tbn, 30720 tbc (default)
Metadata:
handler_name : VideoHandler
Without adding the AV_CODEC_FLAG_GLOBAL_HEADER flag, I get a clean output from ffprobe, but the video still doesn't play. Notice it thinks the frame rate is 30.51, I'm not sure why.
C:\ffmpeg>ffprobe MyMovieMakerMovie.mp4
ffprobe version 4.2.2 Copyright (c) 2007-2019 the FFmpeg developers
built with gcc 9.2.1 (GCC) 20200122
configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt
libavutil 56. 31.100 / 56. 31.100
libavcodec 58. 54.100 / 58. 54.100
libavformat 58. 29.100 / 58. 29.100
libavdevice 58. 8.100 / 58. 8.100
libavfilter 7. 57.100 / 7. 57.100
libswscale 5. 5.100 / 5. 5.100
libswresample 3. 5.100 / 3. 5.100
libpostproc 55. 5.100 / 55. 5.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'MyMovieMakerMovie.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.29.100
Duration: 00:00:01.97, start: 0.000000, bitrate: 20530 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x480, 20528 kb/s, 30.51 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler

Windows Socket and Authentication build failed when including Poco-Library

I have written a C++ program to authenticate windows user which is working seamlessly when Poco Library (Event) has not been included. I have a infinite while loop (while(true)) that needs to be halted when no request are coming from the serer application. Socket read runs independently in a separate thread.
Compiler : MingW 7.2
C++ Standard : C++14
Package Manager : Msys2
Architecture : x64
I am getting an error :
g++ -c -g -D__DEBUG -I/C/msys64/mingw64/include/boost -I/C/msys64/mingw64/include `pkg-config --cflags libconfig++` `pkg-config --cflags gnutls` -std=c++14 -MMD -MP -MF "build/Debug/MinGW-Windows/Authenticate.o.d" -o build/Debug/MinGW-Windows/Authenticate.o Authenticate.cpp
In file included from C:/msys64/mingw64/include/Poco/Foundation.h:102:0,
from C:/msys64/mingw64/include/Poco/Event.h:23,
from Common.hpp:41,
from Authenticate.hpp:19,
from Authenticate.cpp:14:
C:/msys64/mingw64/include/Poco/Platform_WIN32.h:179:92: note: #pragma message: Compiling POCO on Windows without #define POCO_WIN32_UTF8 is deprecated.
#pragma message("Compiling POCO on Windows without #define POCO_WIN32_UTF8 is deprecated.")
^
Authenticate.cpp: In member function 'bool Authenticate::authenticateUserCommandLine(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string, std::__cxx11::string&)':
Authenticate.cpp:30:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:30:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
Authenticate.cpp:32:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:32:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
Authenticate.cpp: In member function 'bool Authenticate::authenticateUserCommandLine(std::__cxx11::string, std::__cxx11::string, std::__cxx11::string&)':
Authenticate.cpp:54:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:54:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
Authenticate.cpp:56:26: error: 'LogonUser' was not declared in this scope
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
Authenticate.cpp:56:26: note: suggested alternative: 'LogonUserW'
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
^~~~~~~~~
LogonUserW
If I remove #include <Poco/Event.h> the program works properly without error.
If I add #define POCO_WIN32_UTF8, I have to replace LogonUser with LogonUserW. The biggest issue I have with adding #define POCO_WIN32_UTF8 is that I am getting an error at ::GetLastError() saying function not found.
LoginUser Usage :
if(password.length() == 0)
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), NULL, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
else
logonReturnVal = LogonUser(userName.c_str(), domain.c_str(), password.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token);
::GetLastError() Usage :
string Error::GetLastErrorAsString(void)
{
//Get the error message, if any.
DWORD errorMessageID = ::GetLastError();
if(errorMessageID == 0)
return string(); //No error message has been recorded
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
string message(messageBuffer, size);
//Free the buffer.
LocalFree(messageBuffer);
return message;
}
The problem was that I had included Poco/Event.h before windows.h. Poco/Event.h needs #define POCO_WIN32_UTF8 to be defined before including the header which caused the problem.
The problem was solved by including windows.h before defining #define POCO_WIN32_UTF8 which in turn was defined before including Poco/Event.h.

Segmenting the strings received from serial port

I am receiving sensor datas through the serial port using Xbee module. The sensors are connected to Arduino and they are sending datas to the zigbee connected to my laptop. here, is the code i am using to show the received datas.
#include <fcntl.h>
#include <stdio.h>
#include <termios.h>
#include <stdlib.h>
#include <string.h>
/* Change to the baud rate of the port B2400, B9600, B19200 etc as per Arduino board is sending */
#define SPEED B9600
/* Change to the serial port you want to use /dev/ttyUSB0, /dev/ttyS0, etc. */
#define PORT "/dev/ttyS1"
/* Sensor raw datas */
int accLowX, accLowY, accLowZ;
int accHighX, accHighY, accHighZ;
int main( ){
int fd = open( PORT, O_RDONLY | O_NOCTTY );
if (fd <0) {perror(PORT); exit(-1); }
struct termios options;
bzero(&options, sizeof(options));
options.c_cflag = SPEED | CS8 | CLOCAL | CREAD | IGNPAR;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &options);
int r;
char buf[255];
char sensorDatas[255];
while( 1 ){
r = read( fd, buf, 255 );
buf[r]=0;
memcpy(sensorDatas, buf, strlen(buf)+1);
printf( "%s", sensorDatas);
// separate the strings for sensor datas
//
}
}
My Output of received datas are:
56-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:341 AHZ:421
57-ALX:350 ALY:349 ALZ:351 AHX:354 AHY:341 AHZ:422
58-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
59-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
60-ALX:350 ALY:349 ALZ:351 AHX:352 AHY:342 AHZ:422
61-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:421
62-ALX:350 ALY:349 ALZ:351 AHX:354 AHY:342 AHZ:422
63-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
64-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
65-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:421
66-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:421
67-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
68-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
69-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:341 AHZ:421
70-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
71-ALX:350 ALY:349 ALZ:351 AHX:352 AHY:342 AHZ:422
72-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
73-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
74-ALX:350 ALY:349 ALZ:351 AHX:352 AHY:342 AHZ:422
75-ALX:350 ALY:349 ALZ:351 AHX:352 AHY:342 AHZ:422
76-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
77-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
78-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:421
79-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
80-ALX:350 ALY:350 ALZ:351 AHX:353 AHY:343 AHZ:422
81-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
82-ALX:350 ALY:349 ALZ:351 AHX:353 AHY:342 AHZ:422
Here i cannot use strlen function as it gives me the output 0 as r is set zo zero. without knowing the string length, i cannot proceed to segment it to get the following datas.
Consider for received string 56, I want to store the following value in each iteration in the following the variables
accLowX = 350, accLowY = 349, accLowZ=351
accHighX =353, accHighY = 341, accHighZ =421;
How can i do it?
I would start by creating a string array and put each line in it (with getline maybe?) Then, you can use split function of boost and use a space as a delimiter. Then, put all of these in a temporary array. http://www.cplusplus.com/faq/sequences/strings/split/ -> Boost String Algorithms: Split
After, just use the find (http://www.cplusplus.com/reference/string/string/find/) to identify each parameter and use a switch case for each one. Or, take the array and use it directly, since all position will be the same (ex: [0] = ALX:(Number), [1] = ALY:(Number), etc). Hope this help.
You can use sscanf , something like this -
if(sscanf(s,"%*[^:]:%d %*[^:]:%d %*[^:]:%d %*[^:]:%d %*[^:]:%d %*[^:]:%d"
,&accLowX,&accLowY,&accLowZ,&accHighX,&accHighY,&accHighZ))==6){
// do something
}
After your valuable suggestions, I found this way to solve my problem. This code is inspired by this CodeSource
Modified Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BAUDRATE B9600 /* baudrate settings are defined in <asm/termbits.h>, which is included by <termios.h> */
#define MODEMDEVICE "/dev/ttyS1" /* change this definition for the correct port */
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
int main()
{
int fd,c, res;
struct termios oldtio,newtio;
char buf[255];
char sensorDatas[255];
/* Sensor raw datas */
int accLowX, accLowY, accLowZ;
int accHighX, accHighY, accHighZ;
/*
Open modem device for reading and writing and not as controlling tty
because we don't want to get killed if linenoise sends CTRL-C.
*/
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
if(fd <0) {
perror(MODEMDEVICE);
exit(-1);
}
tcgetattr(fd,&oldtio); /* save current serial port settings */
//bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
/*
BAUDRATE: Set bps rate. You could also use cfsetispeed and cfsetospeed.
CRTSCTS : output hardware flow control (only used if the cable has
all necessary lines. See sect. 7 of Serial-HOWTO)
CS8 : 8n1 (8bit,no parity,1 stopbit)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters
*/
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
/*
IGNPAR : ignore bytes with parity errors
ICRNL : map CR to NL (otherwise a CR input on the other computer
will not terminate input)
otherwise make device raw (no other input processing)
*/
newtio.c_iflag = IGNPAR | ICRNL;
/*
Raw output.
*/
newtio.c_oflag = 0;
/*
ICANON : enable canonical input
disable all echo functionality, and don't send signals to calling program
*/
newtio.c_lflag = ICANON;
/*
initialize all control characters
default values can be found in /usr/include/termios.h, and are given
in the comments, but we don't need them here
*/
newtio.c_cc[VINTR] = 0; /* Ctrl-c */
newtio.c_cc[VQUIT] = 0; /* Ctrl-\ */
newtio.c_cc[VERASE] = 0; /* del */
newtio.c_cc[VKILL] = 0; /* # */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VSWTC] = 0; /* '\0' */
newtio.c_cc[VSTART] = 0; /* Ctrl-q */
newtio.c_cc[VSTOP] = 0; /* Ctrl-s */
newtio.c_cc[VSUSP] = 0; /* Ctrl-z */
newtio.c_cc[VEOL] = 0; /* '\0' */
newtio.c_cc[VREPRINT] = 0; /* Ctrl-r */
newtio.c_cc[VDISCARD] = 0; /* Ctrl-u */
newtio.c_cc[VWERASE] = 0; /* Ctrl-w */
newtio.c_cc[VLNEXT] = 0; /* Ctrl-v */
newtio.c_cc[VEOL2] = 0; /* '\0' */
/*
now clean the modem line and activate the settings for the port
*/
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
/*
terminal settings done, now handle input
In this example, inputting a 'z' at the beginning of a line will
exit the program.
*/
while (STOP==FALSE) { /* loop until we have a terminating condition */
/* read blocks program execution until a line terminating character is
input, even if more than 255 chars are input. If the number
of characters read is smaller than the number of chars available,
subsequent reads will return the remaining chars. res will be set
to the actual number of characters actually read */
res = read(fd,buf,255);
memcpy(sensorDatas, buf, strlen(buf)+1);
buf[res]=0; /* set end of string, so we can printf */
sensorDatas[res]=0;
printf("%s", sensorDatas);
/* Segmentation of Datas received from Arduino */
if(sscanf(sensorDatas,"%*[^:]:%d %*[^:]:%d %*[^:]:%d %*[^:]:%d %*[^:]:%d %*[^:]:%d"
,&accLowX,&accLowY,&accLowZ,&accHighX,&accHighY,&accHighZ)==6) {
// do something
printf( "accLowX : %d\n", accLowX);
printf( "accLowY : %d\n", accLowY);
printf( "accLowZ : %d\n", accLowZ);
}
}
/* restore the old port settings */
tcsetattr(fd,TCSANOW,&oldtio);
}