First a couple of tips.
ALWAYS remember to initialize pointers and buffers :
BYTE *pchTesto = nullptr;
BYTE *pchBuffOut = nullptr;
WORD *pLen = nullptr;
FILE *fp = nullptr;
PRINTER_INFO_2 *pprint = nullptr;
CHAR chBarcode[256] = { 0 };
TCHAR chDriverName[256] = { 0 };
TCHAR chDoc[256] = { 0 };
Second, the number 256 appears many places in your code. Repeated use of literal values is not a good practice. It is better to use a constant value like :
const int BufferSize = 255;
CHAR chBarcode[BufferSize+1] = { 0 };
TCHAR chDriverName[BufferSize+1] = { 0 };
TCHAR chDoc[BufferSize+1] = { 0 };
I use +1 in each declaration to reserve a spot for the null terminator of the string. Then the function calls will look like this :
_tcscpy_s(chDoc, BufferSize, _T("Label zebra"));
_tcscpy_s(chDriverName, BufferSize, pprint->pDriverName);
and you will always have a null-terminated string and the copy will never overflow.
One problem is this :
CT2A temp(cs); pchTesto = (BYTE *)(char *)temp;
because later you try to free that memory. Check out the implementation of C2TA. It is actually a class that manages its own memory so you are trying to free an invalid memory pointer. You can also use this class to do that :
CW2AEX Class | Microsoft Learn[
^].
This is one example of why the STL's
unique_ptr
class is so useful. It automatically deletes the memory when the object falls out of scope. Here is documentation on it :
https://cplusplus.com/ : unique_ptr[
^]. I highly recommend that you read up on that and give it a try.