Programmatically change VersionInfo of a foreign DLL - c

I am trying to programmatically change the VersionInfo attributes of a DLL file. I used this article as reference.
#include <iostream>
#include <stdio.h>
#include <windows.h>
int main(int argc, char** argv) {
LPCTSTR lpszFile = "E:\\_test\\rand_test\\test.dll";
DWORD dwHandle,
dwSize;
struct {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// determine the size of the resource information
dwSize = GetFileVersionInfoSize(lpszFile, &dwHandle);
if (0 < dwSize)
{
unsigned char* lpBuffer = (unsigned char*) malloc(dwSize);
// Get whole VersionInfo resource/structure
GetFileVersionInfo(lpszFile, 0, dwSize, lpBuffer);
char strSubBlock[37]; // fits "\\StringFileInfo\\xxxxxxxx\\CompanyName\0"
LPTSTR pValueBuffer;
HANDLE hResource = BeginUpdateResource(lpszFile, FALSE);
if (NULL != hResource)
{
UINT uTemp;
// get the language information
if (!VerQueryValue(lpBuffer, "\\VarFileInfo\\Translation", (LPVOID *) &lpTranslate, &uTemp) != FALSE)
{
printf("Error 1\n");
return 1;
}
sprintf(strSubBlock, "\\StringFileInfo\\%04x%04x\\CompanyName", lpTranslate->wLanguage, lpTranslate->wCodePage);
if (!VerQueryValue(lpBuffer, (LPTSTR) ((LPCTSTR) strSubBlock), (LPVOID *) &pValueBuffer, &uTemp)) {
printf("Error 2\n");
return 1;
}
// PROBLEM!!!
// (pValueBuffer-lpBuffer) is 0x438 (longer than the Versioninfo resource!) but should be 0xB8
// so, pValueBuffer does not point to the actual company name.
ZeroMemory(pValueBuffer, strlen(pValueBuffer) * sizeof(TCHAR));
strcpy(pValueBuffer, "My Company, Inc."); // String may only become smaller or equal, never bigger than strlen(pValueBuffer)
if (UpdateResource(hResource,
RT_VERSION,
MAKEINTRESOURCE(VS_VERSION_INFO),
lpTranslate->wLanguage, // or 0
lpBuffer,
dwSize) != FALSE)
{
EndUpdateResource(hResource, FALSE);
}
}
free(lpBuffer);
}
return 0;
}
I think I have understood everything the code does. The plan is to read the Versioninfo block, then find the position where e.g. the CompanyName lies using VerQueryValue, then change the data, and then write it back using UpdateResource.
But there is a problem: VerQueryValue should output the position where the CompanyName string lies. But instead, it gives a pointer location, which is a few hundred bytes away, so it points somewhere outside the VersionInfo structure.
What am I doing wrong and how can I make it work?
(Also, does anybody know if there is a more elegant way to do this task, maybe even remove the limitation that the string has to be smaller or equal to the original?)

version resource this is serialized tree. if you want modify it - you need deserialize it to tree structure in memory, modify node, and serialize to new memory.
despite in msdn defined several Version Information Structures, really all it have common format
struct RsrcHeader
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[];
// aligned on 4*n
// BYTE Value[wValueLength]; // if (wType == 0)
// or
// WCHAR Value[wValueLength]; // if (wType == 1)
// every element aligned on 4*n
// RsrcHeader childs[];
};
so possible write common parse and serialize procedures
#if DBG
#define DBG_OPT(x) _CRT_UNPARENTHESIZE(x)
#else
#define DBG_OPT(x)
#endif
class RsrcNode
{
struct RsrcHeader
{
WORD wLength;
WORD wValueLength;
WORD wType;
WCHAR szKey[];
};
C_ASSERT(sizeof(RsrcHeader) == 6);
RsrcNode* _first, *_next;
PCWSTR _name;
const void* _pvValue;
ULONG _cbValue;
WORD _wValueLength;
WORD _wType;
DBG_OPT((PCSTR _prefix)); // only for debug output
public:
bool ParseResourse(PVOID buf, ULONG size, ULONG* pLength, PCSTR prefix);
RsrcNode(DBG_OPT((PCSTR prefix = "")))
: _next(0), _first(0) DBG_OPT((, _prefix(prefix)))
{
}
~RsrcNode();
bool IsStringValue() const
{
return _wType;
}
const void* getValue(ULONG& cb)
{
cb = _cbValue;
return _pvValue;
}
void setValue(const void* pv, ULONG cb)
{
_pvValue = pv, _cbValue = cb;
_wValueLength = (WORD)(_wType ? cb / sizeof(WCHAR) : cb);
}
RsrcNode* find(const PCWSTR strings[], ULONG n);
ULONG GetSize() const;
PVOID Store(PVOID buf, ULONG* pcb) const;
};
bool RsrcNode::ParseResourse(PVOID buf, ULONG size, ULONG* pLength, PCSTR prefix)
{
union {
PVOID pv;
RsrcHeader* ph;
ULONG_PTR up;
PCWSTR sz;
};
pv = buf;
if (size < sizeof(RsrcHeader) || (up & 3))
{
return false;
}
WORD wType = ph->wType;
ULONG wValueLength = ph->wValueLength, wLength = ph->wLength;
ULONG cbValue = 0;
switch (wType)
{
case 1:
cbValue = wValueLength * sizeof(WCHAR);
break;
case 0:
cbValue = wValueLength;
break;
default:
return false;
}
*pLength = wLength;
if (wLength > size || wLength < sizeof(RsrcHeader) || cbValue >= (wLength -= sizeof(RsrcHeader)))
{
return false;
}
wLength -= cbValue;
sz = ph->szKey, _name = sz;
do
{
if (wLength < sizeof(WCHAR))
{
return false;
}
wLength -= sizeof(WCHAR);
} while (*sz++);
DbgPrint("%s%S {\n", prefix, _name);
if (up & 3)
{
if (wLength < 2)
{
return false;
}
up += 2, wLength -= 2;
}
_wType = wType, _wValueLength = (WORD)wValueLength, _cbValue = cbValue, _pvValue = pv;
if (wValueLength && wType)
{
if (sz[wValueLength - 1])
{
return false;
}
DbgPrint("%s\t%S\n", prefix, sz);
}
if (wLength)
{
if (!*--prefix) return false;
up += wValueLength;
do
{
if (up & 3)
{
if (wLength < 2)
{
return false;
}
up += 2;
if (!(wLength -= 2))
{
break;
}
}
if (RsrcNode* node = new RsrcNode(DBG_OPT((prefix))))
{
node->_next = _first, _first = node;
if (node->ParseResourse(ph, wLength, &size, prefix))
{
continue;
}
}
return false;
} while (up += size, wLength -= size);
prefix++;
}
DbgPrint("%s}\n", prefix);
return true;
}
RsrcNode::~RsrcNode()
{
if (RsrcNode* next = _first)
{
do
{
RsrcNode* cur = next;
next = next->_next;
delete cur;
} while (next);
}
DBG_OPT((DbgPrint("%s%S\n", _prefix, _name)));
}
RsrcNode* RsrcNode::find(const PCWSTR strings[], ULONG n)
{
PCWSTR str = *strings++;
if (!str || !wcscmp(str, _name))
{
if (!--n)
{
return this;
}
if (RsrcNode* next = _first)
{
do
{
if (RsrcNode* p = next->find(strings, n))
{
return p;
}
} while (next = next->_next);
}
}
return 0;
}
ULONG RsrcNode::GetSize() const
{
ULONG size = sizeof(RsrcHeader) + (1 + (ULONG)wcslen(_name)) * sizeof(WCHAR);
if (_cbValue)
{
size = ((size + 3) & ~3) + _cbValue;
}
if (RsrcNode* next = _first)
{
do
{
size = ((size + 3) & ~3) + next->GetSize();
} while (next = next->_next);
}
return size;
}
PVOID RsrcNode::Store(PVOID buf, ULONG* pcb) const
{
union {
RsrcHeader* ph;
ULONG_PTR up;
PVOID pv;
};
pv = buf;
ph->wType = _wType;
ph->wValueLength = _wValueLength;
ULONG size = (1 + (ULONG)wcslen(_name)) * sizeof(WCHAR), cb;
memcpy(ph->szKey, _name, size);
up += (size += sizeof(RsrcHeader));
if (_cbValue)
{
up = (up + 3) & ~3;
memcpy(pv, _pvValue, _cbValue);
up += _cbValue;
size = ((size + 3) & ~3) + _cbValue;
}
if (RsrcNode* next = _first)
{
do
{
up = (up + 3) & ~3;
pv = next->Store(pv, &cb);
size = ((size + 3) & ~3) + cb;
} while (next = next->_next);
}
reinterpret_cast<RsrcHeader*>(buf)->wLength = (WORD)size;
*pcb = size;
return pv;
}
with this helper structure we can update version in next way:
#include "VerHlp.h"
BOOL UpdateVersion(PVOID pvVersion, ULONG cbVersion, PVOID& pvNewVersion, ULONG& cbNewVersion)
{
BOOL fOk = FALSE;
char prefix[16];
memset(prefix, '\t', sizeof(prefix));
prefix[RTL_NUMBER_OF(prefix) - 1] = 0;
*prefix = 0;
if (RsrcNode* node = new RsrcNode)
{
if (node->ParseResourse(pvVersion, cbVersion, &cbVersion, prefix + RTL_NUMBER_OF(prefix) - 1))
{
static const PCWSTR str[] = {
L"VS_VERSION_INFO", L"StringFileInfo", 0, L"CompanyName"
};
if (RsrcNode *p = node->find(str, RTL_NUMBER_OF(str)))
{
if (p->IsStringValue())
{
ULONG cb;
const void* pvCompanyName = p->getValue(cb);
DbgPrint("CompanyName: %S\n", pvCompanyName);
static WCHAR CompanyName[] = L"[ New Company Name ]";
if (cb != sizeof(CompanyName) ||
memcmp(pvCompanyName, CompanyName, sizeof(CompanyName)))
{
p->setValue(CompanyName, sizeof(CompanyName));
cbVersion = node->GetSize();
if (pvVersion = LocalAlloc(0, cbVersion))
{
node->Store(pvVersion, &cbNewVersion);
pvNewVersion = pvVersion;
fOk = TRUE;
}
}
}
}
}
delete node;
}
return fOk;
}
struct EnumVerData
{
HANDLE hUpdate;
BOOL fDiscard;
};
BOOL CALLBACK EnumResLangProc(HMODULE hModule,
PCWSTR lpszType,
PCWSTR lpszName,
WORD wIDLanguage,
EnumVerData* Ctx
)
{
if (HRSRC hResInfo = FindResourceExW(hModule, lpszType, lpszName, wIDLanguage))
{
if (HGLOBAL hg = LoadResource(hModule, hResInfo))
{
if (ULONG size = SizeofResource(hModule, hResInfo))
{
if (PVOID pv = LockResource(hg))
{
if (UpdateVersion(pv, size, pv, size))
{
if (UpdateResource(Ctx->hUpdate, lpszType, lpszName, wIDLanguage, pv, size))
{
Ctx->fDiscard = FALSE;
}
LocalFree(pv);
}
}
}
}
}
return TRUE;
}
ULONG UpdateVersion(PCWSTR FileName)
{
ULONG dwError = NOERROR;
EnumVerData ctx;
if (ctx.hUpdate = BeginUpdateResource(FileName, FALSE))
{
ctx.fDiscard = TRUE;
if (HMODULE hmod = LoadLibraryExW(FileName, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE))
{
if (!EnumResourceLanguages(hmod, RT_VERSION,
MAKEINTRESOURCE(VS_VERSION_INFO),
(ENUMRESLANGPROCW)EnumResLangProc, (LONG_PTR)&ctx))
{
dwError = GetLastError();
}
FreeLibrary(hmod);
}
else
{
dwError = GetLastError();
}
if (!dwError && !EndUpdateResourceW(ctx.hUpdate, ctx.fDiscard))
{
dwError = GetLastError();
}
}
else
{
dwError = GetLastError();
}
return dwError;
}

Related

Binary search loop is not breaking when the search element input is not prsenting in the sorted array

I am implementing the binary search in C as below, but when I'm passing the element which is not available in the sorted array, the code is enter into infinite loop since the midelement is repetitively calculating the same value (midelement is 4, and then start index becomes 5 (elementtofind > InputArray[midelement]), end index is 4, hence again returns the mid element as 4) after the 9th iteration of the loop, can anyone find how could I improve this logic.
#define MAX_NUM_INPUT (358U)
uint16 InputArray[MAX_NUM_INPUT] = {0x0103, 0x0104, 0x0109, 0x010A, 0x0133, 0x0180, 0x181, 0x183,.....upto 358 elements};
int main()
{
boolean elmntFound = 0;
uint16 elmntTofnd = 0x0134;
elmntFound = SearchPassedElement(0, MAX_NUM_INPUT, elmntTofnd);
if(elmntFound == 0)
{
printf("elementfound");
}
else
{
printf("elementNOTfound");
}
}
static boolean SearchPassedElement (uint16 FrstElmntIdx,uint16 LstElmntIdx, uint16 ElmntToFind)
{
boolean ReturnValue = 1;
uint16 startIdx = FrstElmntIdx;
uint16 endIdx = LstElmntIdx;
uint16 loc_midElmntIdx;
boolean OperationStatus = FALSE;
if(LstElmntIdx >= FrstElmntIdx)
{
while (OperationStatus == FALSE)
{
loc_midElmntIdx = (startIdx + endIdx) / 2U ;
if (ElmntToFind == InputArray[loc_midElmntIdx])
{
OperationStatus = TRUE;
ReturnValue = 0 ;
}
else if (ElmntToFind > InputArray[loc_midElmntIdx])
{
/* if entire array was already checked*/
if (startIdx == endIdx)
{
OperationStatus = TRUE;
ReturnValue = 1 ;
}
else /* othewise, */
{
startIdx = loc_midElmntIdx + 1U;
}
}
else
{
/* if entire array was already checked*/
if (startIdx == endIdx)
{
OperationStatus = TRUE;
ReturnValue = 1 ;
}
else /* othewise, */
{
endIdx = loc_midElmIdx - 1U ;
}
}
}
}
else
{
loopCntr = 0;
/* Incorrect input arguments */
ReturnValue = 1;
}
return ReturnValue;
}
I have found one logic as if the midelemnt is returned with same value for more than 3 times the lop shall be breaked, and evaluating the same.
static boolean SearchPassedElement (uint16 FrstElmntIdx,uint16 LstElmntIdx, uint16 ElmntToFind)
{
boolean ReturnValue = 1;
uint16 startIdx = FrstElmntIdx;
uint16 endIdx = LstElmntIdx;
uint16 loc_midElmntIdx;
boolean OperationStatus = FALSE;
uint16 prev_loc_midElmIdx = 0;
uint16 is_midElmIdxSame_count = 0;
if(LstElmntIdx >= FrstElmntIdx)
{
while (OperationStatus == FALSE)
{
loc_midElmntIdx = (startIdx + endIdx) / 2U ;
if (ElmntToFind == InputArray[loc_midElmntIdx])
{
OperationStatus = TRUE;
ReturnValue = 0 ;
}
else if (ElmntToFind > InputArray[loc_midElmntIdx])
{
/* if entire array was already checked*/
if (startIdx == endIdx)
{
OperationStatus = TRUE;
ReturnValue = 1 ;
}
else /* othewise, */
{
startIdx = loc_midElmntIdx + 1U;
}
}
else
{
/* if entire array was already checked*/
if (startIdx == endIdx)
{
OperationStatus = TRUE;
ReturnValue = 1 ;
}
else /* othewise, */
{
endIdx = loc_midElmIdx - 1U ;
}
}
if(prev_loc_midElmIdx != loc_midElmIdx)
{
prev_loc_midElmIdx = loc_midElmIdx;
}
else
{
is_midElmIdxSame_count++;
/*as the divisor is 2 the same value can't return more that 2 times, hence if the same value is return more than
* 2 times the loop should be braked
*/
if(is_midElmIdxSame_count == 3)
{
elmntNotFnd = 3;
/* Stop operation and return failure*/
OperationStatus = TRUE;
ReturnValue = 1 ;
}
}
}
}
else
{
loopCntr = 0;
/* Incorrect input arguments */
ReturnValue = 1;
}
return ReturnValue;
}
There's no such type called boolean in C. You have to #include <stdbool.h> to use the bool type. The same thing for uint16, you have to #include <stdint.h> and use uint16_t.
And your code is very complicated. You needlessly use a lot of variables to get one simple thing done.
Here is a more compact version:
bool binary_search(size_t start, size_t end, const uint16_t elem, const uint16_t array[])
{
while (start < end) {
size_t middle = (start + end) / 2;
if (elem == array[middle])
return true;
if (elem < array[middle])
end = middle;
else
start = middle + 1;
}
return false;
}
It returns true if the element is found, false otherwise.
Example:
int main(void)
{
uint16_t array[] = {1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U};
const size_t size = sizeof array / sizeof array[0];
const uint16_t elem = 10U;
printf("%s\n", binary_search(0, size, elem, array) ? "Found" : "Not found");
}
Found
Few things to note:
size_t is the appropriate type for indexing arrays.
Use const (i.e. read-only) when you don't modify your variables.
Don't write C in Pascal style.

Why is config_read_file() returning config_false?

I have been using libconfig for config files in a project. When I remove the double quotes from sources by source_to_use, config_read_file() returns config_true and also has a syntax error. The syntax error will cause my getter for the source_to_use option to go to the default case. Also because of this my getter for the source array, will also go to the else case. Could this just be me making a simple syntax error with the libconfig format?
This is the config file I am using:
#config for walld
#colors
colors = TRUE;
source_to_use: "sources";
default:
[
"/home/seth/Pictures/kimi.png"
];
sources:
[
"/home/seth/.walld/persona",
"/home/seth/.walld/image-urls"
];
This is the function I have reading it:
settings* read_config(const char* config_file, const char* home_dir) {
settings* options = malloc(sizeof(settings));
config_t config;
config_setting_t* setting;
const char* source;
int colors;
config_init(&config);
if (config_read_file(&config, config_file) == CONFIG_TRUE) {
config_destroy(&config);
return NULL;
}
if (config_lookup_bool(&config, "colors", &colors)) {
options->colors = colors;
}
else {
options->colors = 0;
}
if (config_lookup_string(&config, "source_to_use", &source)) {
//NOP
}
else {
source = "default";
}
setting = config_lookup(&config, source);
if (setting != NULL) {
int count = config_setting_length(setting);
linked_node* entry_point = add_node_to_list(NULL, NULL);
linked_node* current = entry_point;
options->sources = entry_point;
for (int i = 0; i < count; i++) {
char* item = config_setting_get_string_elem(setting, i);
current = add_node_to_list(current, item);
}
}
else {
options->sources = malloc(sizeof(linked_node));
int char_count = snprintf(NULL, 0, "%s%s", home_dir, "/.walld/images");
if (char_count <= 0) {
//tough luck
abort();
}
char* default_folder = malloc(char_count + 1U);
if (default_folder == NULL) {
//tough luck
abort();
}
snprintf(default_folder, char_count + 1U, "%s%s", home_dir, "/.walld/images");
options->sources->image = default_folder;
}
config_destroy(&config);
return options;
}
In your read_config function, your first if is:
if (config_read_file(&config, config_file) == CONFIG_TRUE) {
config_destroy(&config);
return NULL;
}
The sense of the if is reversed, so you'll return a NULL if the read of the file is valid.
So, you want to reverse the sense of this if:
if (config_read_file(&config, config_file) != CONFIG_TRUE) {
config_destroy(&config);
return NULL;
}
Or you could [probably] use:
if (config_read_file(&config, config_file) == CONFIG_FALSE) {

avcodec_encode_video2 the memory usage is very high

code:
```
#include "pch.h"
#include
extern "C"
{
#ifndef __STDC_CONSTANT_MACROS
#define __STDC_CONSTANT_MACROS
#endif
#include <libavcodec/avcodec.h>
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavutil/avutil.h"
#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include <libavutil/rational.h>
//#include "libavutil/avassert.h"
//#include "libavutil/attributes.h"
//#include "libavutil/avassert.h"
//#include "libavutil/frame.h"
//#include "libavutil/imgutils.h"
//#include "internal1.h"
//#include "libavutil/samplefmt.h"
}
#include <vld.h>
//#include "avcodec.h"
//#include "frame_thread_encoder.h"
//#include "internal.h"
// Globals
AVCodec* m_pCodec = NULL;
AVStream *m_pStream = NULL;
AVOutputFormat* m_pFormat = NULL;
AVFormatContext* m_pFormatContext = NULL;
AVCodecContext* m_pCodecContext = NULL;
AVFrame* m_pFrame = NULL;
int m_frameIndex;
// Output format
AVPixelFormat m_pixType = AV_PIX_FMT_NV12;
// Use for mpeg4
//AVPixelFormat m_pixType = AV_PIX_FMT_YUV420P;
// Output frame rate
int m_frameRate = 30;
// Output image dimensions
int m_imageWidth = 256;
int m_imageHeight = 1537;
// Number of frames to export
int m_frameCount = 20000;
// Output file name
const char* m_fileName = "test.h264";
// Output file type
const char* m_fileType = "H264";
// Codec name used to encode
const char* m_encoderName = "h264_qsv";
// use for mpeg4
//const char* m_encoderName = "mpeg4";
// Target bit rate
int m_targetBitRate = 400000;
void addVideoStream()
{
m_pStream = avformat_new_stream(m_pFormatContext, m_pCodec);
m_pStream->id = m_pFormatContext->nb_streams - 1;
m_pStream->time_base = m_pCodecContext->time_base;
m_pStream->codec->pix_fmt = m_pixType;
m_pStream->codec->flags = m_pCodecContext->flags;
m_pStream->codec->width = m_pCodecContext->width;
m_pStream->codec->height = m_pCodecContext->height;
m_pStream->codec->time_base = m_pCodecContext->time_base;
m_pStream->codec->bit_rate = m_pCodecContext->bit_rate;
}
AVFrame* allocatePicture(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *frame;
frame = av_frame_alloc();
if (!frame)
{
return NULL;
}
frame->format = pix_fmt;
frame->width = width;
frame->height = height;
int checkImage = av_image_alloc(frame->data, frame->linesize, width, height, pix_fmt, 32);
if (checkImage < 0)
{
return NULL;
}
return frame;
}
bool initialize()
{
AVRational frameRate;
frameRate.den = m_frameRate;
frameRate.num = 1;
av_register_all();
m_pCodec = avcodec_find_encoder_by_name(m_encoderName);
if (!m_pCodec)
{
return false;
}
m_pCodecContext = avcodec_alloc_context3(m_pCodec);
m_pCodecContext->width = m_imageWidth;
m_pCodecContext->height = m_imageHeight;
m_pCodecContext->time_base = frameRate;
m_pCodecContext->gop_size = 0;
m_pCodecContext->pix_fmt = m_pixType;
m_pCodecContext->codec_id = m_pCodec->id;
m_pCodecContext->bit_rate = m_targetBitRate;
av_opt_set(m_pCodecContext->priv_data, "+CBR", "", 0);
return true;
}
bool startExport()
{
m_frameIndex = 0;
char fakeFileName[512];
int checkAllocContext = avformat_alloc_output_context2(&m_pFormatContext, NULL, m_fileType, fakeFileName);
if (checkAllocContext < 0)
{
return false;
}
if (!m_pFormatContext)
{
return false;
}
m_pFormat = m_pFormatContext->oformat;
if (m_pFormat->video_codec != AV_CODEC_ID_NONE)
{
addVideoStream();
int checkOpen = avcodec_open2(m_pCodecContext, m_pCodec, NULL);
if (checkOpen < 0)
{
return false;
}
m_pFrame = allocatePicture(m_pCodecContext->pix_fmt, m_pCodecContext->width, m_pCodecContext->height);
if (!m_pFrame)
{
return false;
}
m_pFrame->pts = 0;
}
int checkOpen = avio_open(&m_pFormatContext->pb, m_fileName, AVIO_FLAG_WRITE);
if (checkOpen < 0)
{
return false;
}
av_dict_set(&(m_pFormatContext->metadata), "title", "QS Test", 0);
int checkHeader = avformat_write_header(m_pFormatContext, NULL);
if (checkHeader < 0)
{
return false;
}
return true;
}
int processFrame(AVPacket& avPacket)
{
avPacket.stream_index = 0;
avPacket.pts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base);
avPacket.dts = av_rescale_q(m_pFrame->pts, m_pStream->codec->time_base, m_pStream->time_base);
m_pFrame->pts++;
int retVal = av_interleaved_write_frame(m_pFormatContext, &avPacket);
return retVal;
}
bool exportFrame()
{
int success = 1;
int result = 0;
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
AVPacket* avPacket1 = new AVPacket();
av_init_packet(avPacket1);
avPacket1->data = NULL;
avPacket1->size = 0;
fflush(stdout);
std::cout << "Before avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
success = avcodec_encode_video2(m_pCodecContext, &avPacket, m_pFrame, &result);
std::cout << "After avcodec_encode_video2 for frame: " << m_frameIndex << std::endl;
if (result)
{
success = processFrame(avPacket);
}
av_packet_unref(&avPacket);
av_free_packet(&avPacket);
//av_frame_free(&m_pFrame);
m_frameIndex++;
return (success == 0);
}
void endExport()
{
int result = 0;
int success = 0;
if (m_pFrame)
{
while (success == 0)
{
AVPacket avPacket;
av_init_packet(&avPacket);
avPacket.data = NULL;
avPacket.size = 0;
fflush(stdout);
success = avcodec_encode_video2(m_pCodecContext, &avPacket, NULL, &result);
if (result)
{
success = processFrame(avPacket);
}
av_packet_unref(&avPacket);
if (!result)
{
break;
}
}
}
if (m_pFormatContext)
{
av_write_trailer(m_pFormatContext);
if (m_pFrame)
{
av_frame_free(&m_pFrame);
}
avio_closep(&m_pFormatContext->pb);
avformat_free_context(m_pFormatContext);
m_pFormatContext = NULL;
}
}
void cleanup()
{
if (m_pFrame || m_pCodecContext)
{
if (m_pFrame)
{
av_frame_free(&m_pFrame);
}
if (m_pCodecContext)
{
avcodec_close(m_pCodecContext);
av_free(m_pCodecContext);
}
}
}
int main()
{
bool success = true;
if (initialize())
{
if (startExport())
{
for (int loop = 0; loop < m_frameCount; loop++)
{
if (!exportFrame())
{
std::cout << "Failed to export frame\n";
success = false;
break;
}
}
endExport();
}
else
{
std::cout << "Failed to start export\n";
success = false;
}
cleanup();
}
else
{
std::cout << "Failed to initialize export\n";
success = false;
}
if (success)
{
std::cout << "Successfully exported file\n";
}
return 1;
}
```
When I set the m_imageHeight to 1536, the memory usage is very high. But when set to 1535 or 1537 or other values, the memory usage is normal, can you tell me why?
I have navigated to avcodec_encode_video2
enter link description here
I am using the code from the link
I have updated to the latest IntelĀ® Graphics Driver

eAthena - Adding 4 bytes to end of packet

I'm working on rewriting some source from eAthena. I need to add 4 bytes to the end of the packet. I'm trying to understand how. Wouldn't WFIFOL(sd->fd, len) = 0 add 4 bytes? Do I need to do a SWAP32 on this? Still learning thanks.
int clif_sendadditem(USER *sd, int num) {
char buf[128];
char buf2[128];
char *name = NULL;
char* owner = NULL;
int namelen;
int len;
int id;
//if(!sd->status.inventory[num].custom) {
id=sd->status.inventory[num].id;
//} else {
// id=sd->status.inventory[num].custom;
//}
if (id > 0 && !strcmpi(itemdb_name(id), "??")) {
memset(&sd->status.inventory[num], 0, sizeof(sd->status.inventory[num]));
return 0;
}
if (strlen(sd->status.inventory[num].real_name)) {
name = sd->status.inventory[num].real_name;
} else {
//if(!sd->status.inventory[num].custom) {
name = itemdb_name(id);
//} else {
// name = itemdb_namec(id);
//}
}
if (sd->status.inventory[num].amount > 1) {
sprintf(buf, "%s (%d)", name, sd->status.inventory[num].amount);
} else if(itemdb_type(sd->status.inventory[num].id)==ITM_SMOKE) {
//if(!sd->status.inventory[num].custom) {
sprintf(buf, "%s [%d %s]",name,sd->status.inventory[num].dura,itemdb_text(sd->status.inventory[num].id));
//} else {
// sprintf(buf, "%s [%d %s]",name,sd->status.inventory[num].dura,itemdb_textc(sd->status.inventory[num].custom));
//}
} else {
strcpy(buf, name);
}
namelen = strlen(buf);
if (!session[sd->fd])
{
session[sd->fd]->eof = 8;
return 0;
}
WFIFOHEAD(sd->fd, 255);
WFIFOB(sd->fd, 0) = 0xAA;
WFIFOB(sd->fd, 3) = 0x0F;
//WFIFOB(sd->fd, 4) = 0x03;
WFIFOB(sd->fd, 5) = num+1;
//if(!sd->status.inventory[num].custom) {
WFIFOW(sd->fd, 6) = SWAP16(itemdb_icon(id));
WFIFOB(sd->fd, 8) = itemdb_iconcolor(id);
//} else {
// WFIFOW(sd->fd, 6) = SWAP16(itemdb_iconc(id));
// WFIFOB(sd->fd, 8) = itemdb_iconcolorc(id);
//}
WFIFOB(sd->fd, 9) = namelen;
memcpy(WFIFOP(sd->fd, 10), buf, namelen);
len=namelen+1;
//if(!sd->status.inventory[num].custom) {
WFIFOB(sd->fd,len+9)=strlen(itemdb_name(id));
strcpy(WFIFOP(sd->fd,len+10),itemdb_name(id));
len+=strlen(itemdb_name(id))+1;
//} else {
// WFIFOB(sd->fd,len+9)=strlen(itemdb_namec(id));
// strcpy(WFIFOP(sd->fd,len+10),itemdb_namec(id));
// len+=strlen(itemdb_namec(id))+1;
//}
WFIFOL(sd->fd,len+9)=SWAP32(sd->status.inventory[num].amount);
len+=4;
if((itemdb_type(id)<3) || (itemdb_type(id)>17)) {
WFIFOB(sd->fd,len+9)=1;
WFIFOL(sd->fd,len+10)=0;
WFIFOB(sd->fd, len + 14) = 0;
len+=6;
} else {
WFIFOB(sd->fd,len+9)=0;
WFIFOL(sd->fd,len+10)=SWAP32(sd->status.inventory[num].dura);
WFIFOB(sd->fd, len + 14) = 0; //REPLACE WITH PROTECTED
len+=6;
}
if(sd->status.inventory[num].owner_id) {
owner=map_id2name(sd->status.inventory[num].owner_id);
WFIFOB(sd->fd,len+9)=strlen(owner);
strcpy(WFIFOP(sd->fd,len+10),owner);
len+=strlen(owner)+1;
FREE(owner);
} else {
WFIFOB(sd->fd,len+9)=0; //len of owner
len+=1;
}
//WFIFOW(sd->fd, len + 9) = SWAP16(0);
WFIFOW(sd->fd, 1) = SWAP16(len + 6);
WFIFOSET(sd->fd, encrypt(sd->fd));
return 0;
}
I was miscounting and changed the commented
//WFIFOW(sd->fd, len + 9) = SWAP16(0);
to
WFIFOL(sd->fd, len + 9) = SWAP32(0);
and then changed to len+10 at end

Segmentation fault: 11 in c program (dynamic memory allocation)

I have the following piece of code which allocates some memory.
Some used initialisations:
#define MEM_POOL_SIZE 600
typedef struct {
size size;
mem_status status;
} mem_chunk_header;
unsigned char* ptr;
When I call this function as follows
ma_malloc(600)
it should return NULL.
But I get a segmentation fault: 11.
I tried using GDB, but then I run into different problems...
void* ma_malloc(size tsize)
{
mem_chunk_header header;
unsigned char* searchPtr = ptr;
int oldSize = 0;
int stop = 0;
while(((searchPtr-ptr)/sizeof(unsigned char) < MEM_POOL_SIZE) && (stop >= 0))
{
if((*searchPtr = 0xFF) && ((getSize(searchPtr) >= (tsize))))
{
stop = -1;
}
else
{
if(getSize(searchPtr) == 0)
{
return NULL;
}
else
{
searchPtr += (getSize(searchPtr)+header.size);
}
}
}
if(stop == 0)
{
printf("%s\n","No free space available");
return NULL;
}
else
{
oldSize = getSize(searchPtr);
//Update header
*searchPtr = 0xAA;
*(searchPtr+1) = (unsigned char) ((tsize)/256);
*(searchPtr+2) = (unsigned char) ((tsize)%256);
//Update footer
updateFooter(searchPtr);
//New overhead
unsigned char* newPtr = (searchPtr+(getSize(searchPtr))+header.size);
unsigned char* nextPtr = (unsigned char*) (searchPtr+oldSize+header.size);
int leftoverSize = ((nextPtr-newPtr)/sizeof(unsigned char));
if(leftoverSize == 0)
{
//Do nothing
}
else
if(leftoverSize <= header.size)
{
unsigned int tempSize = getSize(searchPtr) + leftoverSize;
//Update header
*(searchPtr+1) = (unsigned char) (tempSize/256);
*(searchPtr+2) = (tempSize%256);
//footer
updateFooter(searchPtr);
}
else
{
//Update header
*newPtr = 0xFF;
*(newPtr+1) = (unsigned char) ((leftoverSize-header.size)/256);
*(newPtr+2) = (unsigned char) ((leftoverSize-header.size)%256);
//Update footer
updateFooter(newPtr);
}
}
return searchPtr;
}
I've been looking at this for a while now, but I can't see why it is giving me this error.

Resources