Object initialization differences in afxmem.cpp - c++

I have an object in function z which I'm accessing from functions x and y. The problem is that it's initialized through different functions in the afxmem.cpp (VS 11.0 file).
Here's my code;
classA
{
public:
ADesign *a_d;
};
void classA::functionZ()
{
a_d = new ADesign;
}
//functionX and functionY both calls same function
void classB::functionX()
{
ca.functionZ();
}
void classB::functionY()
{
ca.functionZ();
}
//sample initializer for ADesign
ADesign::ADesign()
:doc_(0)
{
version_number = 7.82f;
d_file = "";
c_file = "";
angle = ID_ANGLE_MER;
machine_type = MACHINE_COMPRESS;
//...etc
}
When it's being initialized, it goes through these functions in afxmem.cpp for function x
void* PASCAL
CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
{
return ::operator new(nSize, _AFX_CLIENT_BLOCK, lpszFileName, nLine);
}
void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
{
#ifdef _AFX_NO_DEBUG_CRT
UNUSED_ALWAYS(nType);
UNUSED_ALWAYS(lpszFileName);
UNUSED_ALWAYS(nLine);
return ::operator new(nSize);
#else
void* pResult;
#ifdef _AFXDLL
_PNH pfnNewHandler = _pfnUninitialized;
#endif
for (;;)
{
pResult = _malloc_dbg(nSize, nType, lpszFileName, nLine);
if (pResult != NULL)
return pResult;
#ifdef _AFXDLL
if (pfnNewHandler == _pfnUninitialized)
{
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
pfnNewHandler = pState->m_pfnNewHandler;
}
if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
break;
#else
if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0)
break;
#endif
}
return pResult;
#endif
}
And this function in afxmem.cpp for function y;
void* __cdecl operator new(size_t nSize)
{
void* pResult;
#ifdef _AFXDLL
_PNH pfnNewHandler = _pfnUninitialized;
#endif
for (;;)
{
#if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
pResult = _malloc_dbg(nSize, _NORMAL_BLOCK, NULL, 0);
#else
pResult = malloc(nSize);
#endif
if (pResult != NULL)
return pResult;
#ifdef _AFXDLL
if (pfnNewHandler == _pfnUninitialized)
{
AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
pfnNewHandler = pState->m_pfnNewHandler;
}
if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
break;
#else
if (_afxNewHandler == NULL || (*_afxNewHandler)(nSize) == 0)
break;
#endif
}
return pResult;
}
When it goes through function y, it doesn't get initialized properly. I'm accessing the program through the command line for function y.
Is there a reason as to why the initialization is happening in 2 different ways for the same object?
Thanks.

At the beginning of your .cpp files you may or may not have this line:
#define new DEBUG_NEW
If this line is present, then new will end up invoking this function:
void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
if it is not present then new will end up invoking this function:
void* __cdecl operator new(size_t nSize)
That's internal MFC debugging stuff.
But that doesn't explain why something doesn't get initialized properly. You need to elaborate your question, it's not clear enough.

Related

Memory leak when using IShellItem2.GetString()

I'm using the following code to enumerate the contents of the Recyclebin Shell folder and get the file type of each item.
The code gives the expected results but if I call the function in a loop it looks like there's some memory leak when using the IshellItem2 GetString function (see attached screenshot at the end).
Am I cleaning up everything properly?
Am I misinterpreting the results?
void Test1()
{
// Get recyclebin ishellitem
IShellItem* psiRecycleBin;
if (SUCCEEDED(SHGetKnownFolderItem(FOLDERID_RecycleBinFolder, KF_FLAG_DEFAULT,
NULL, IID_PPV_ARGS(&psiRecycleBin))))
{
// Get ishellitem contents enumerator
IEnumShellItems* pesi;
if (SUCCEEDED(psiRecycleBin->BindToHandler(NULL, BHID_EnumItems, IID_PPV_ARGS(&pesi))))
{
IShellItem* psi;
while (pesi->Next(1, &psi, NULL) == S_OK)
{
// Get ishellitem2 from ishellitem
IShellItem2* psi2;
if (SUCCEEDED(psi->QueryInterface(IID_PPV_ARGS(&psi2))))
{
// Get the item file type string
LPWSTR fileType = NULL;
if (SUCCEEDED(psi2->GetString(PKEY_ItemTypeText, &fileType)))
{
CoTaskMemFree(fileType);
}
psi2->Release();
}
psi->Release();
}
pesi->Release();
}
psiRecycleBin->Release();
}
}
And I'm calling it in loop like this:
#define STRICT_TYPED_ITEMIDS
#include <shlobj.h>
#include <propkey.h>
#include <iostream>
void Test1();
int main()
{
(void)CoInitialize(NULL);
std::cout << "Enumerating recyclebin items..\n";
for (int ii = 0; ii < 5000; ii++)
{
Test1();
}
CoUninitialize();
return 0;
}
When debugging this console program in VS in the memory diagnostics window this is what I get:
Thanks for the help
yes, here really exist memory leak, related to HIDDENRECYCLEBINDATAV2 structure from shell32.dll
partial definition of it:
struct HIDDENRECYCLEBINDATAV2
{
//... some mebers
FILETIME time;
PWSTR pszLocationBeforeDelete = 0; // !!! not released
PWSTR pszLocationInRecycleBin = 0; // !!! not released
HRESULT Serialize(PBYTE *, PUSHORT);
static HRESULT Deserialize(
_In_reads_bytes_opt_(cbStream) const BYTE *pbStream ,
_In_ USHORT cbStream,
_Out_ HIDDENRECYCLEBINDATAV2 ** pphrbd);
static HRESULT Initialize(HIDDENRECYCLEBINDATAV1 const *, HIDDENRECYCLEBINDATAV2**);
};
this structure hold 2 strings - file path from where it deleted ( pszLocationBeforeDelete - this is my name, i don't know original) and current file path in Recycle Bin ( pszLocationInRecycleBin - again my name)
this names allocated inside Deserialize method, by call IStream_ReadStrLong and must be freed with CoTaskMemFree. but how i found - CoTaskMemFree never called for this two strings.
pseudo code for Deserialize :
static HRESULT HIDDENRECYCLEBINDATAV2::Deserialize(
_In_reads_bytes_opt_(cbInit) const BYTE *pbStream ,
_In_ USHORT cbStream,
_Out_ HIDDENRECYCLEBINDATAV2 ** pphrbd)
{
HRESULT hr = E_FAIL;
if (HIDDENRECYCLEBINDATAV2 *phrbd = new HIDDENRECYCLEBINDATAV2)
{
if (IStream *pStream = SHCreateMemStream(pbStream, cbStream))
{
if (0 <= (hr = IStream_ReadStrLong(pStream, &phrbd->pszLocationBeforeDelete)) &&
0 <= (hr = IStream_ReadStrLong(pStream, &phrbd->pszLocationInRecycleBin)))
{
*pphrbd = phrbd, phrbd = 0;
}
pStream->Release();
}
CoTaskMemFree(phrbd); // !! error, need delete phrbd
}
return hr;
}
and it called from CBitBucket::_ValidateItem :
HRESULT InitDeletedItem(PCWSTR pszLocationBeforeDelete, PCWSTR pszLocationBeforeDelete, DELETEDITEM *);
static HRESULT CBitBucket::_ValidateItem(_ITEMIDLIST_RELATIVE const *, DELETEDITEM ** ppdi)
{
HIDDENRECYCLEBINDATAV2 * phrbd;
if (0 <= HIDDENRECYCLEBINDATAV2::Deserialize(pbStream, cbStream, &phrbd))
{
if (DELETEDITEM * pdi = new DELETEDITEM)
{
if (0 <= InitDeletedItem( phrbd->pszLocationBeforeDelete,
phrbd->pszLocationInRecycleBin, pdi))
{
*ppdi = pdi, pdi = 0;
}
if (pdi) delete pdi;
}
CoTaskMemFree(phrbd); // !! error, need delete phrbd
}
}
in both functions - memory for HIDDENRECYCLEBINDATAV2 simply released with CoTaskMemFree api, but memory for strings inside this structure not released. i think need add
HIDDENRECYCLEBINDATAV2::~HIDDENRECYCLEBINDATAV2()
{
CoTaskMemFree(pszLocationInRecycleBin);
CoTaskMemFree(pszLocationBeforeDelete);
}
to this structure and call delete instead CoTaskMemFree
how possible found this ? i hook RtlAllocateHeap and RtlFreeHeap before second call to Test1() (important do this not on first call, because during first call may be additional libs load, some differed initialization, etc.. - all this can distort the real result)and log all alloc/free calls in current thread. also i replace while (pesi->Next..) to if (pesi->Next..) (usually one iteration is enough ). and i found that count of alloc on 2 more than count of free. so i easy found from where this 2 allocations- inside IStream_ReadStrLong. then i set breakpoint here and easy view from where this called :
CBitBucket::_ValidateItem
HIDDENRECYCLEBINDATAV2::Deserialize
IStream_ReadStrLong
CoTaskMemAlloc
partial demo code for log:
struct AI
{
PVOID BaseAddress;
PVOID From;
ULONG Size;
ULONG Flags;
};
struct TID
{
AI *pi;
ULONG nAlloc, nFree, nCells, MaxAllocDelta;
BOOL bNotLog;
TID()
{
RtlZeroMemory(this, sizeof(*this));
}
};
BOOLEAN NTAPI hook_RtlFreeHeap(PVOID HeapHandle, ULONG Flags, PVOID BaseAddress )
{
TID* p = RTL_FRAME<TID>::get();
if (!p || p->bNotLog)
{
return RtlFreeHeap(HeapHandle, Flags, BaseAddress) != 0;
}
p->bNotLog = TRUE;
if (!RtlFreeHeap(HeapHandle, Flags, BaseAddress))
{
__debugbreak();
}
if (BaseAddress)
{
AI* pi = p->pi;
ULONG n = p->nCells;
do
{
if (pi->BaseAddress == BaseAddress)
{
pi->BaseAddress = 0;
p->nFree++;
break;
}
} while (pi++, --n);
if (!n)
{
__debugbreak();
}
}
p->bNotLog = FALSE;
return TRUE;
}
PVOID NTAPI hook_RtlAllocateHeap( PVOID HeapHandle, ULONG Flags, SIZE_T Size )
{
TID* p = RTL_FRAME<TID>::get();
if (!p || p->bNotLog)
{
return RtlAllocateHeap(HeapHandle, Flags, Size);
}
p->bNotLog = TRUE;
if (PVOID BaseAddress = RtlAllocateHeap(HeapHandle, Flags, Size))
{
AI* pi = p->pi;
ULONG n = p->nCells;
do
{
if (!pi->BaseAddress)
{
pi->BaseAddress = BaseAddress;
pi->From = _ReturnAddress();
pi->Size = (ULONG)Size;
pi->Flags = Flags;
p->nAlloc++;
ULONG k = p->nAlloc - p->nFree;
if (k > p->MaxAllocDelta)
{
p->MaxAllocDelta = k;
}
break;
}
} while (pi++, --n);
if (!n)
{
__debugbreak();
}
p->bNotLog = FALSE;
return BaseAddress;
}
return 0;
}
void TestEx()
{
enum { cell_count = 0x1000 };
if (AI* pi = new AI[cell_count])
{
Test1();// first call
// hook RtlAllocateHeap + RtlFreeHeap
{
RtlZeroMemory(pi, cell_count * sizeof(AI));
RTL_FRAME<TID> f;
f.pi = pi;
f.nCells = cell_count;
Test1();// second call
DbgPrint("%x(%x) %x\n", f.nAlloc, f.nFree, f.MaxAllocDelta);
if (f.nAlloc - f.nFree)
{
ULONG n = cell_count;
AI* qi = pi;
do
{
if (qi->BaseAddress)
{
DbgPrint("%p> %x %x\n", qi->From, qi->Size, qi->Flags);
}
} while (qi++, --n);
}
}
delete [] pi;
}
}

GetProcAddress fails [duplicate]

This question already has answers here:
Exporting functions from a DLL with dllexport
(4 answers)
Closed 4 years ago.
I have a fucntion in dynamic library which looks like:
namespace Dll {
int MyDll::getQ() {
srand(time(0));
int q = rand();
while (!isPrime(q) || q < 100) {
q = rand();
}
return q;
}
}
Function getQ() in .h file:
#ifdef _EXPORT
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
namespace Dll
{
class MyDll
{
public:
static DLL_EXPORT int __stdcall getQ();
}
}
And finally LoadLibrary peace of code from another consoleApp:
typedef int(__stdcall *CUSTOM_FUNCTION)();
int main()
{
HINSTANCE hinstance;
CUSTOM_FUNCTION proccAddress;
BOOL freeLibrarySuccess;
BOOL proccAddressSuccess = FALSE;
int result;
hinstance = LoadLibrary(TEXT("Dll.dll"));
if (hinstance != NULL)
{
proccAddress = (CUSTOM_FUNCTION)GetProcAddress(hinstance, "getQ");
if (proccAddress != NULL)
{
proccAddressSuccess = TRUE;
result = (*proccAddress)();
printf("function called\n");
printf("%d", result);
}
freeLibrarySuccess = FreeLibrary(hinstance);
}
if (!hinstance)
printf("Unable to call the dll\n");
if (!proccAddressSuccess)
printf("Unable to call the function\n");
}
So I tried to fix this several times but I always get "Unable to call the function". The code connects to the library so the problem is somewhere near the function.
I'll appreciate if someone will point me on my mistake.
You are missing an Extern "C".
If you don't, names will be c++ mangled and you cannot find them with getQ name only. In addition, it will not be reliable to do so, because name mangling may change.
Another topic is here to: _stdcall vs _cdecl

Registering a custom CodeInsight manager - What am I doing wrong?

This is a subsequent question to my fist one, asking how to register a custom CodeInsight manager to the IDE with C++Builder.
I switched my code to Remy Lebeau's version with the #pragma startup and #pragma exitdirectives.
What now happens when I try to use it (see my code below) is this:
With CodeGuard set to active:
I hit F9 -> Project compiles well (except for [TLIB Warning] Warning: library was too large for page size, rebuilt with page size 32)
A second instance of bds.exe starts (because i set it as the host app)
In the 2nd instance I try to install my package wich results in the following error:
I deactivate CodeGuard in the project debugging settings and try it again and now it seems to work, as I can see a sequence of MessageBoxes:
TMyCodeInsightSymbolList::TMyCodeInsightSymbolList
TMyCodeInsightManager::TMyCodeInsightManager
TMyCodeInsightManager::GetIDString
TMyCodeInsightManager::GetIDString
TMyCodeInsightManager::GetIDString
TMyCodeInsightManager::GetIDString
TMyCodeInsightManager::GetIDString
Now I create a new VCL Forms Application in the debugging instance and enter
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
this->|
}
in TForm1's constructor.
The resulting MessageBoxes:
TMyCodeInsightManager::HandlesFile
TMyCodeInsightManager::GetEnabled
TMyCodeInsightManager::AllowCodeInsight
TMyCodeInsightManager::EditorTokenValidChars
TMyCodeInsightManager::PreValidateCodeInsight
TMyCodeInsightManager::EditorTokenValidChars
TMyCodeInsightManager::InvokeCodeCompletion
TMyCodeInsightManager::GetSymbolList
TMyCodeInsightSymbolList::GetCount
TMyCodeInsightSymbolList::~TMyCodeInsightSymbolList
TMyCodeInsightManager::GetSymbolList
Error:
It drives me crazy...so what the heck am I doing wrong here?
{...}
Furthermore, in the IDE setting in the 2nd instance at Editor Options -> CodeInsight I see my new entry in the ComboBox Source file type but when I select it, there's an out of range error, so I think the IDE is missing some registry entries for my completion manager or stuff. Am I right?
Now, here's my code:
my_completion.cpp
#pragma hdrstop
#pragma package(smart_init)
#include "my_codeinsight_manager.h"
static int FCodeManagerIndex = -1;
void DoRegister()
{
_di_IOTACodeInsightServices CIS;
if (BorlandIDEServices->Supports(CIS))
FCodeManagerIndex = CIS->AddCodeInsightManager(new TMyCodeInsightManager);
}
#pragma startup DoRegister
void DoUnregister()
{
_di_IOTACodeInsightServices CIS;
if ((FCodeManagerIndex != -1) && BorlandIDEServices->Supports(CIS))
CIS->RemoveCodeInsightManager(FCodeManagerIndex);
}
#pragma exit DoUnregister
#pragma argsused
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
my_codeinsight_manager.h
#ifndef my_codeinsight_managerH
#define my_codeinsight_managerH
//---------------------------------------------------------------------------
#include <memory>
#include <System.SysUtils.hpp>
#include <ToolsAPI.hpp>
#include "my_codeinsight_symbollist.h"
//---------------------------------------------------------------------------
class TMyCodeInsightManager : public TCppInterfacedObject<IOTANotifier, IOTACodeInsightManager>
{
public:
TMyCodeInsightManager();
virtual __fastcall ~TMyCodeInsightManager();
String __fastcall GetName();
String __fastcall GetIDString();
bool __fastcall GetEnabled();
void __fastcall SetEnabled(bool AValue) ;
TSysCharSet __fastcall EditorTokenValidChars(bool APreValidating);
void __fastcall AllowCodeInsight(bool& Allow, const WideChar AKey);
bool __fastcall PreValidateCodeInsight(const String AStr);
bool __fastcall IsViewerBrowsable(int AIndex);
bool __fastcall GetMultiSelect();
void __fastcall GetSymbolList(_di_IOTACodeInsightSymbolList& ASymbolList);
void __fastcall OnEditorKey(WideChar AKey, bool& ACloseViewer, bool& AAccept);
bool __fastcall HandlesFile(const String AFileName);
String __fastcall GetLongestItem();
void __fastcall GetParameterList(_di_IOTACodeInsightParameterList& AParameterList);
void __fastcall GetCodeInsightType(WideChar AChar, int AElement, TOTACodeInsightType& ACodeInsightType, TOTAInvokeType& AInvokeType);
bool __fastcall InvokeCodeCompletion(TOTAInvokeType AHowInvoked, String& AStr);
bool __fastcall InvokeParameterCodeInsight(TOTAInvokeType AHowInvoked, int& ASelectedIndex);
void __fastcall ParameterCodeInsightAnchorPos(TOTAEditPos& AEdPos);
int __fastcall ParameterCodeInsightParamIndex(const TOTAEditPos& AEdPos);
String __fastcall GetHintText(int AHintLine, int AHintCol);
String __fastcall GetOptionSetName();
bool __fastcall GotoDefinition(String& AFileName, int& ALineNum, int AIndex=0xFFFFFFFF);
void __fastcall Done(bool AAccepted, bool& ADisplayParams);
__property String Name = {read=GetName};
__property bool MultiSelect = {read=GetMultiSelect};
__property bool Enabled = {read=GetEnabled, write=SetEnabled};
/* IOTANotifier */
void __fastcall AfterSave() {}
void __fastcall BeforeSave() {}
void __fastcall Destroyed() {}
void __fastcall Modified() {}
private:
std::unique_ptr<TMyCodeInsightSymbolList> FSymbolList;
TSysCharSet FSysCharSet;
};
my_codeinsight_manager.cpp
#include <vcl.h>
#pragma hdrstop
#include "my_codeinsight_manager.h"
// ---------------------------------------------------------------------------
#pragma package(smart_init)
TMyCodeInsightManager::TMyCodeInsightManager()
: FSymbolList(std::unique_ptr<TMyCodeInsightSymbolList>(new TMyCodeInsightSymbolList))
{
FSysCharSet = TSysCharSet() << 'A' << 'B' << 'C' << 'D' << 'E' << 'F' << 'G' << 'H' << 'I' << 'J' << 'K'
<< 'L' << 'M' << 'N' << 'O' << 'P' << 'Q' << 'R' << 'S' << 'T' << 'U' << 'V' << 'W'
<< 'X' << 'Y' << 'Z'
<< 'a' << 'b' << 'c' << 'd' << 'e' << 'f' << 'g' << 'h' << 'i' << 'j' << 'k' << 'l'
<< 'm' << 'n' << 'o' << 'p' << 'q' << 'r' << 's' << 't' << 'u' << 'v' << 'w' << 'x'
<< 'y' << 'z'
<< '0' << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9'
<< '+' << '-' << '*' << '/' << '^' << '\\' << '(' << ')' << '[' << ']' << '{' << '}'
<< '=' << '!' << '<' << '>' << '\'' << '\"' << '$' << ',' << ';' << ':' << '5' << '!'
<< '&' << '?' << '_' << '#' << '#'
<< 0x08 << 0x09 << 0x0B << 0x0C << 0x0D;
ShowMessage(L"TMyCodeInsightManager::TMyCodeInsightManager");
}
//---------------------------------------------------------------------------
__fastcall TMyCodeInsightManager::~TMyCodeInsightManager()
{
ShowMessage(L"TMyCodeInsightManager::~TMyCodeInsightManager");
}
//---------------------------------------------------------------------------
String __fastcall TMyCodeInsightManager::GetName()
{
ShowMessage(L"TMyCodeInsightManager::GetName");
return L"MyCodeInsightLanguage";
}
//----------------------------------------------------------------------------
String __fastcall TMyCodeInsightManager::GetIDString()
{
ShowMessage(L"TMyCodeInsightManager::GetIDString");
return L"My.CodeInsight";
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::GetEnabled()
{
ShowMessage(L"TMyCodeInsightManager::GetEnabled");
return true;
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::SetEnabled(bool AValue)
{
ShowMessage(L"TMyCodeInsightManager::SetEnabled");
}
//----------------------------------------------------------------------------
TSysCharSet __fastcall TMyCodeInsightManager::EditorTokenValidChars(bool APreValidating)
{
ShowMessage(L"TMyCodeInsightManager::EditorTokenValidChars");
return FSysCharSet;
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::AllowCodeInsight(bool& AAllow, const WideChar AKey)
{
ShowMessage(L"TMyCodeInsightManager::AllowCodeInsight");
AAllow = true;
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::PreValidateCodeInsight(const String AStr)
{
ShowMessage(L"TMyCodeInsightManager::PreValidateCodeInsight");
return true;
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::IsViewerBrowsable(int AIndex)
{
ShowMessage(L"TMyCodeInsightManager::IsViewerBrowsable");
return true; // # TO DO #
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::GetMultiSelect()
{
ShowMessage(L"TMyCodeInsightManager::GetMultiSelect");
return false;
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::GetSymbolList(_di_IOTACodeInsightSymbolList& ASymbolList)
{
ASymbolList = FSymbolList.get();
ShowMessage(L"TMyCodeInsightManager::GetSymbolList");
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::OnEditorKey(WideChar AKey, bool& ACloseViewer, bool& AAccept)
{
ACloseViewer = true;
AAccept = false;
ShowMessage(L"TMyCodeInsightManager::OnEditorKey");
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::HandlesFile(const String AFileName)
{
ShowMessage(L"TMyCodeInsightManager::HandlesFile");
String FileExt = ExtractFileExt(AFileName);
if ( (FileExt == L".c")
|| (FileExt == L".cpp")
|| (FileExt == L".h")
|| (FileExt == L".hpp")
|| (FileExt == L".cc")
|| (FileExt == L".cp")
|| (FileExt == L".cxx") )
{
return true;
}
else
{
return false;
}
}
//----------------------------------------------------------------------------
String __fastcall TMyCodeInsightManager::GetLongestItem()
{
ShowMessage(L"TMyCodeInsightManager::GetLongestItem");
return String(L"dddddddddddddddddddddd");
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::GetParameterList(_di_IOTACodeInsightParameterList& AParameterList)
{
AParameterList = NULL;
ShowMessage(L"TMyCodeInsightManager::GetParameterList");
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::GetCodeInsightType(WideChar AChar, int AElement, TOTACodeInsightType& ACodeInsightType, TOTAInvokeType& AInvokeType)
{
AInvokeType = itManual;
if ( (AElement != atString) && (AChar != 0x0001) && (AElement == atComment) )
{
switch (AChar)
{
case 0x0000:
ACodeInsightType = citCodeInsight;
break;
case 0x0001:
ACodeInsightType = citParameterCodeInsight;
break;
case 0x0002:
ACodeInsightType = citBrowseCodeInsight;
break;
case 0x0003:
ACodeInsightType = citHintCodeInsight;
break;
case L'.':
ACodeInsightType = citCodeInsight;
AInvokeType = itTimer;
break;
case L'(':
ACodeInsightType = citParameterCodeInsight;
AInvokeType = itTimer;
break;
default:
ACodeInsightType = citNone;
}
}
ShowMessage(L"TMyCodeInsightManager::GetCodeInsightType");
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::InvokeCodeCompletion(TOTAInvokeType AHowInvoked, String& AStr)
{
switch (AHowInvoked)
{
case itAuto:
break;
case itManual:
break;
case itTimer:
break;
}
AStr = L"IAmASymbolText";
return true;
}
//----------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::InvokeParameterCodeInsight(TOTAInvokeType AHowInvoked, int& ASelectedIndex)
{
switch (AHowInvoked)
{
case itAuto:
break;
case itManual:
break;
case itTimer:
break;
}
ShowMessage(L"TMyCodeInsightManager::OnvokeParameterCodeInsight");
return true; // # TO DO #
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::ParameterCodeInsightAnchorPos(TOTAEditPos& AEdPos)
{
ShowMessage(L"TMyCodeInsightManager::ParameterCodeInsightAnchorPos");
}
//----------------------------------------------------------------------------
int __fastcall TMyCodeInsightManager::ParameterCodeInsightParamIndex(const TOTAEditPos& AEdPos)
{
ShowMessage(L"TMyCodeInsightManager::ParameterCodeInsightParamIndex");
return 0;
}
//----------------------------------------------------------------------------
String __fastcall TMyCodeInsightManager::GetHintText(int AHintLine, int AHintCol)
{
ShowMessage(L"TMyCodeInsightManager::GetHintText");
return L"NoHint";
}
//----------------------------------------------------------------------------
String __fastcall TMyCodeInsightManager::GetOptionSetName()
{
ShowMessage(L"TMyCodeInsightManager::GetOptionSetName");
return L"MyCodeInsight";
}
//---------------------------------------------------------------------------
bool __fastcall TMyCodeInsightManager::GotoDefinition(String &AFileName, int& ALineNum, int AIndex)
{
ShowMessage(L"TMyCodeInsightManager::GotoDefinition");
return true;
}
//----------------------------------------------------------------------------
void __fastcall TMyCodeInsightManager::Done(bool AAccepted, bool& ADisplayParams)
{
ShowMessage(L"TMyCodeInsightManager::Done");
}
//----------------------------------------------------------------------------
my_codeinsight_symbollist.h
#ifndef my_codeinsight_symbollistH
#define my_codeinsight_symbollistH
//---------------------------------------------------------------------------
#include <vector>
#include <algorithm>
#include <System.SysUtils.hpp>
#include <ToolsAPI.hpp>
//---------------------------------------------------------------------------
class TMySymbolList
{
public:
TMySymbolList(const String AText=L"", const String AType=L"", const String AClass=L"", const bool AIsReadWrite=false, const bool AIsAbstract=false, const TOTAViewerSymbolFlags AFlag=vsfUnknown, const TOTAViewerVisibilityFlags AVisibilityFlag=vvfPrivate, TOTAProcDispatchFlags AProcDispatchFlag=pdfNone)
: FText(AText),
FType(AType),
FClass(AClass),
FFlag(AFlag),
FVisibilityFlag(AVisibilityFlag),
FProcDispatchFlag(AProcDispatchFlag)
{}
__property String Text = {read=FText, write=FText}; // i.e. 'Form1'
__property String Type = {read=FType, write=FType}; // i.e. 'TForm1'
__property String Class = {read=FClass, write=FClass}; // i.e. 'var', 'function', 'type', etc.
__property bool IsReadWrite = {read=FIsReadWrite, write=FIsReadWrite};
__property bool IsAbstract = {read=FIsAbstract, write=FIsAbstract};
__property TOTAViewerSymbolFlags Flag = {read=FFlag, write=FFlag};
__property TOTAViewerVisibilityFlags VisibilityFlag = {read=FVisibilityFlag, write=FVisibilityFlag};
__property TOTAProcDispatchFlags ProcDispatchFlag = {read=FProcDispatchFlag, write=FProcDispatchFlag};
private:
String FText;
String FType;
String FClass;
bool FIsReadWrite;
bool FIsAbstract;
TOTAViewerSymbolFlags FFlag;
TOTAViewerVisibilityFlags FVisibilityFlag;
TOTAProcDispatchFlags FProcDispatchFlag;
};
//---------------------------------------------------------------------------
class TMyCodeInsightSymbolList : public TCppInterfacedObject<IOTACodeInsightSymbolList>
{
public:
TMyCodeInsightSymbolList();
virtual __fastcall ~TMyCodeInsightSymbolList();
void __fastcall Clear(void);
int __fastcall GetCount(void);
bool __fastcall GetSymbolIsReadWrite(int AIndex);
bool __fastcall GetSymbolIsAbstract(int AIndex);
TOTAViewerSymbolFlags __fastcall GetViewerSymbolFlags(int AIndex);
int __fastcall GetViewerVisibilityFlags(int AIndex);
TOTAProcDispatchFlags __fastcall GetProcDispatchFlags(int AIndex);
void __fastcall SetSortOrder(const TOTASortOrder AValue);
TOTASortOrder __fastcall GetSortOrder(void);
int __fastcall FindIdent(const String AIdent);
bool __fastcall FindSymIndex(const String AIdent, int& AIndex);
void __fastcall SetFilter(const String AFilterText);
String __fastcall GetSymbolText(int AIndex);
String __fastcall GetSymbolTypeText(int AIndex);
String __fastcall GetSymbolClassText(int AIndex);
__property String SymbolClassText[int Index] = {read=GetSymbolClassText};
__property String SymbolTypeText[int Index] = {read=GetSymbolTypeText};
__property String SymbolText[int Index] = {read=GetSymbolText};
__property TOTAViewerSymbolFlags SymbolFlags[int i] = {read=GetViewerSymbolFlags};
__property int SymbolVisibility[int Index] = {read=GetViewerVisibilityFlags};
__property bool SymbolIsAbstract[int Index] = {read=GetSymbolIsAbstract};
__property bool SymbolIsReadWrite[int Index] = {read=GetSymbolIsReadWrite};
__property TOTAProcDispatchFlags FuncDispatchFlags[int Index] = {read=GetProcDispatchFlags};
__property TOTASortOrder SortOrder = {read=GetSortOrder, write=SetSortOrder};
__property int Count = {read=GetCount};
private:
static bool SymbolTextCompare(const TMySymbolList& AX, const TMySymbolList& AY);
std::vector<TMySymbolList> FSymbols;
TOTASortOrder FSortOrder;
};
//---------------------------------------------------------------------------
#endif
my_codeinsight_symbollist.cpp
#include <vcl.h>
#pragma hdrstop
#include "my_codeinsight_symbollist.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
// Constructor
TMyCodeInsightSymbolList::TMyCodeInsightSymbolList()
: FSortOrder(soAlpha)
{
TMySymbol S;
S.Text = L"IAmASymbolText";
S.Type = L"IAmASymbolType";
S.Class = L"IAmASymbolClass";
S.Flag = vsfFunction;
S.VisibilityFlag = vvfPublic;
FSymbols.push_back(S);
FSymbols.push_back(S);
FSymbols.push_back(S);
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::TMyCodeInsightSymbolList");
#endif
}
//---------------------------------------------------------------------------
// Destructor
__fastcall TMyCodeInsightSymbolList::~TMyCodeInsightSymbolList()
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::~TMyCodeInsightSymbolList");
#endif
}
//---------------------------------------------------------------------------
// Implementor should clear its symbol list
void __fastcall TMyCodeInsightSymbolList::Clear(void)
{
FSymbols.clear();
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::Clear");
#endif
}
//----------------------------------------------------------------------------
// Returns the count of the symbols in the list - may be modified by setting a filter
int __fastcall TMyCodeInsightSymbolList::GetCount(void)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetCount");
#endif
return static_cast<int>(FSymbols.size());
}
//----------------------------------------------------------------------------
// Returns whether the symbol is able to be read from and written to
bool __fastcall TMyCodeInsightSymbolList::GetSymbolIsReadWrite(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetSymbolIsReadWrite");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].IsReadWrite;
else
return false;
}
//----------------------------------------------------------------------------
// Returns whether the symbols is abstract. Viewer draws these in the 'need to implement' color
bool __fastcall TMyCodeInsightSymbolList::GetSymbolIsAbstract(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetSymbolIsAbstract");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].IsAbstract;
else
return false;
}
//----------------------------------------------------------------------------
// Return the symbol flags for the item at index 'AIndex'. AIndex is the index in the filtered list
TOTAViewerSymbolFlags __fastcall TMyCodeInsightSymbolList::GetViewerSymbolFlags(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetViewerSymbolFlags");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].Flag;
else
return vsfUnknown;
}
//----------------------------------------------------------------------------
// Return the visibility flags for the item at index 'AIndex'. AIndex is the index in the filtered list
int __fastcall TMyCodeInsightSymbolList::GetViewerVisibilityFlags(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetViewerVisibilityFlags");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].VisibilityFlag;
else
return vvfPrivate; // # TO DO #
}
//----------------------------------------------------------------------------
// Return the procedure flags for the item at index 'AIndex'. AIndex is the index in the filtered list
TOTAProcDispatchFlags __fastcall TMyCodeInsightSymbolList::GetProcDispatchFlags(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetProcDispatchFlags");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].ProcDispatchFlag;
else
return pdfNone;
}
//----------------------------------------------------------------------------
// The list was requested to be sorted by 'AValue'
void __fastcall TMyCodeInsightSymbolList::SetSortOrder(const TOTASortOrder AValue)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::SetSortOrder");
#endif
FSortOrder = AValue;
// Sort order is alphabetically
if (FSortOrder == soAlpha)
{
// Sort Symbol vector alphabetically
std::sort(FSymbols.begin(), FSymbols.end(), SymbolTextCompare);
}
// Sort order is by scope
else if (FSortOrder == soScope)
{
// Sort Symbol vector by scope
// # TO DO #
}
}
//----------------------------------------------------------------------------
// Returns the sort order of the list
TOTASortOrder __fastcall TMyCodeInsightSymbolList::GetSortOrder(void)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetSortOrder");
#endif
return FSortOrder;
}
//----------------------------------------------------------------------------
// Given an identifier, return the index of the closest partial match
int __fastcall TMyCodeInsightSymbolList::FindIdent(const String AIdent)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::FindIdent");
#endif
return 0; // # TO DO # We're not searching at the moment
}
//----------------------------------------------------------------------------
// Given an identifier, find the 'Index' of an exact match in the list and return true. Otherwise return false
bool __fastcall TMyCodeInsightSymbolList::FindSymIndex(const String AIdent, int& AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::FindSymIndex");
#endif
return false; // # TO DO # We aren't matching at the moment
}
//----------------------------------------------------------------------------
// Set the lists filter to 'FilterText'. It is up to the implementor to determine how to filter or if they even want to filter
void __fastcall TMyCodeInsightSymbolList::SetFilter(const String AFilterText)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::SetFilter");
#endif
// # TO DO # : We don't filter at the moment
}
//----------------------------------------------------------------------------
// Return the symbol text for item 'AIndex'. i.e. Form1
String __fastcall TMyCodeInsightSymbolList::GetSymbolText(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetSymbolText");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].Text;
else
return L"";
}
//----------------------------------------------------------------------------
// Return the symbol type text for item 'AIndex'. i.e. TForm1
String __fastcall TMyCodeInsightSymbolList::GetSymbolTypeText(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetSymbolTypeText");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].Type;
else
return L"";
}
//----------------------------------------------------------------------------
// Return the symbol class text for item 'AIndex'. i.e. 'var', 'function', 'type', etc
String __fastcall TMyCodeInsightSymbolList::GetSymbolClassText(int AIndex)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::GetSymbolClassText");
#endif
if (AIndex < static_cast<int>(FSymbols.size()))
return FSymbols[AIndex].Class;
else
return L"";
}
//----------------------------------------------------------------------------
// Returns true, if AX.Text's position is alphabetically before AY.Text's
bool TMyCodeInsightSymbolList::SymbolTextCompare(const TMySymbol& AX, const TMySymbol& AY)
{
#ifdef _DEBUG
ShowMessage(L"TMyCodeInsightSymbolList::SymbolTextCompare");
#endif
return (AnsiCompareStr(AX.Text, AY.Text) == -1);
}
//---------------------------------------------------------------------------

overloading new and delete in c++

HI All,
I was trying to overload new and delete to fix a memory leak problem in my project. But got stuck with some compilation error.
Currently this code is bit shabby
Here is my hdr file
#include <cstddef>
#include <iostream>
#include <list>
#include <stdarg.h>
#include <stdio.h>
using namespace std;
typedef unsigned int DWORD;
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum);
char *OutputDebugString (const char *fmt, ...);
void RemoveTrack(DWORD addr);
void DumpUnfreed();
#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
void * operator new (unsigned int size, const char *file, int line)
{
void *ptr = (void *)malloc(size);
AddTrack((DWORD)ptr, size, file, line);
return(ptr);
}
/*inline void * operator new(unsigned int size)
{
void *ptr = (void *)malloc(size);
AddTrack((DWORD)ptr, size, _FILE_,_LINE_);
return(ptr);
}*/
void operator delete(void *p)
{
RemoveTrack((DWORD)p);
free(p);
}
#endif
char *OutputDebugString (const char *fmt, ...)
{
char *p = NULL;
size_t size = 1024;
int n = 0;
va_list ap;
if((p = (char*) malloc(size)) == NULL)
return NULL;
while(1) {
va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap);
va_end(ap);
if(n > -1 && n < size)
return p;
/* failed: have to try again, alloc more mem. */
if(n > -1) /* glibc 2.1 */
size = n + 1;
else /* glibc 2.0 */
size *= 2; /* twice the old size */
if((p = (char *)realloc (p, size)) == NULL)
return NULL;
}
}
typedef struct information {
DWORD address;
DWORD size;
char file[64];
DWORD line;
} ALLOC_INFO;
typedef list < ALLOC_INFO* > AllocList;
AllocList *allocList;
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum)
{
ALLOC_INFO *info;
if(!allocList) {
//allocList = new AllocList;
allocList = (AllocList*)malloc (sizeof (AllocList));
}
//info = new(ALLOC_INFO);
info = (ALLOC_INFO*) malloc (sizeof (ALLOC_INFO));
info->address = addr;
strncpy(info->file, fname, 63);
info->line = lnum;
info->size = asize;
allocList->insert(allocList->begin(), info);
}
void RemoveTrack(DWORD addr)
{
AllocList::iterator i;
if(!allocList)
if(!allocList)
return;
for(i = allocList->begin(); i != allocList->end(); i++)
{
if((*i)->address == addr)
{
allocList->remove((*i));
break;
}
}
}
void DumpUnfreed()
{
AllocList::iterator i;
DWORD totalSize = 0;
char buf[1024];
if(!allocList)
return;
for(i = allocList->begin(); i != allocList->end(); i++) {
sprintf(buf, "%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d unfreed\n",
(*i)->file, (*i)->line, (*i)->address, (*i)->size);
OutputDebugString("%s",buf);
totalSize += (*i)->size;
}
sprintf(buf, "-----------------------------------------------------------\n");
OutputDebugString("%s",buf);
sprintf(buf, "Total Unfreed: %d bytes\n", totalSize);
OutputDebugString("%s",buf);
}
And my main.cpp is
#include "mynew.h"
int main()
{
char *ptr = new char;
DumpUnfreed();
return 0;
}
When i try to compile i get the following error
[root#dhcppc0 new]# !g
g++ main.cpp -D_DEBUG
mynew.h:25: error: declaration of ‘operator new’ as non-function
main.cpp: In function ‘int main()’:
main.cpp:9: error: no matching function for call to ‘operator new(unsigned int, const char [9], int)’
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:84: note: candidates are: void* operator new(size_t)
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:88: note: void* operator new(size_t, const std::nothrow_t&)
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:94: note: void* operator new(size_t, void*)
I know there is some thing wrong with my #defines, but I am not sure what is wrong.
Can any one please bale me out of this
You've defined your new macro before your functions. Your code ends up looking like:
void *
operator new(__FILE__, __LINE__)(unsigned int size, const char *file, int line)
Which is obviously wrong. Your should move the macro definitions underneath the functions (or better is to keep those functions in a .cpp file you link with.) For what it's worth, new is a keyword and cannot be an identifier, so your program is, strictly speaking, ill-formed.
I recently posted my global memory operators framework. It might help you a bit.
the signature don't match it sould be void* operator new (size_t size).
overriding single object new signature is
static void * operator new(site_t size),
roni

Windows CD Burning API

We need to programatically burn files to CD in a C\C++ Windows XP/Vista application we are developing using Borlands Turbo C++.
What is the simplest and best way to do this? We would prefer a native windows API (that doesnt rely on MFC) so as not to rely on any third party software/drivers if one is available.
We used the following:
Store files in the directory returned by GetBurnPath, then write using Burn. GetCDRecordableInfo is used to check when the CD is ready.
#include <stdio.h>
#include <imapi.h>
#include <windows.h>
struct MEDIAINFO {
BYTE nSessions;
BYTE nLastTrack;
ULONG nStartAddress;
ULONG nNextWritable;
ULONG nFreeBlocks;
};
//==============================================================================
// Description: CD burning on Windows XP
//==============================================================================
#define CSIDL_CDBURN_AREA 0x003b
SHSTDAPI_(BOOL) SHGetSpecialFolderPathA(HWND hwnd, LPSTR pszPath, int csidl, BOOL fCreate);
SHSTDAPI_(BOOL) SHGetSpecialFolderPathW(HWND hwnd, LPWSTR pszPath, int csidl, BOOL fCreate);
#ifdef UNICODE
#define SHGetSpecialFolderPath SHGetSpecialFolderPathW
#else
#define SHGetSpecialFolderPath SHGetSpecialFolderPathA
#endif
//==============================================================================
// Interface IDiscMaster
const IID IID_IDiscMaster = {0x520CCA62,0x51A5,0x11D3,{0x91,0x44,0x00,0x10,0x4B,0xA1,0x1C,0x5E}};
const CLSID CLSID_MSDiscMasterObj = {0x520CCA63,0x51A5,0x11D3,{0x91,0x44,0x00,0x10,0x4B,0xA1,0x1C,0x5E}};
typedef interface ICDBurn ICDBurn;
// Interface ICDBurn
const IID IID_ICDBurn = {0x3d73a659,0xe5d0,0x4d42,{0xaf,0xc0,0x51,0x21,0xba,0x42,0x5c,0x8d}};
const CLSID CLSID_CDBurn = {0xfbeb8a05,0xbeee,0x4442,{0x80,0x4e,0x40,0x9d,0x6c,0x45,0x15,0xe9}};
MIDL_INTERFACE("3d73a659-e5d0-4d42-afc0-5121ba425c8d")
ICDBurn : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE GetRecorderDriveLetter(
/* [size_is][out] */ LPWSTR pszDrive,
/* [in] */ UINT cch) = 0;
virtual HRESULT STDMETHODCALLTYPE Burn(
/* [in] */ HWND hwnd) = 0;
virtual HRESULT STDMETHODCALLTYPE HasRecordableDrive(
/* [out] */ BOOL *pfHasRecorder) = 0;
};
//==============================================================================
// Description: Get burn pathname
// Parameters: pathname - must be at least MAX_PATH in size
// Returns: Non-zero for an error
// Notes: CoInitialize(0) must be called once in application
//==============================================================================
int GetBurnPath(char *path)
{
ICDBurn* pICDBurn;
int ret = 0;
if (SUCCEEDED(CoCreateInstance(CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn))) {
BOOL flag;
if (pICDBurn->HasRecordableDrive(&flag) == S_OK) {
if (SHGetSpecialFolderPath(0, path, CSIDL_CDBURN_AREA, 0)) {
strcat(path, "\\");
}
else {
ret = 1;
}
}
else {
ret = 2;
}
pICDBurn->Release();
}
else {
ret = 3;
}
return ret;
}
//==============================================================================
// Description: Get CD pathname
// Parameters: pathname - must be at least 5 bytes in size
// Returns: Non-zero for an error
// Notes: CoInitialize(0) must be called once in application
//==============================================================================
int GetCDPath(char *path)
{
ICDBurn* pICDBurn;
int ret = 0;
if (SUCCEEDED(CoCreateInstance(CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn))) {
BOOL flag;
WCHAR drive[5];
if (pICDBurn->GetRecorderDriveLetter(drive, 4) == S_OK) {
sprintf(path, "%S", drive);
}
else {
ret = 1;
}
pICDBurn->Release();
}
else {
ret = 3;
}
return ret;
}
//==============================================================================
// Description: Burn CD
// Parameters: None
// Returns: Non-zero for an error
// Notes: CoInitialize(0) must be called once in application
//==============================================================================
int Burn(void)
{
ICDBurn* pICDBurn;
int ret = 0;
if (SUCCEEDED(CoCreateInstance(CLSID_CDBurn, NULL,CLSCTX_INPROC_SERVER,IID_ICDBurn,(LPVOID*)&pICDBurn))) {
if (pICDBurn->Burn(NULL) != S_OK) {
ret = 1;
}
pICDBurn->Release();
}
else {
ret = 2;
}
return ret;
}
//==============================================================================
bool GetCDRecordableInfo(long *FreeSpaceSize)
{
bool Result = false;
IDiscMaster *idm = NULL;
IDiscRecorder *idr = NULL;
IEnumDiscRecorders *pEnumDiscRecorders = NULL;
ULONG cnt;
long type;
long mtype;
long mflags;
MEDIAINFO mi;
try {
CoCreateInstance(CLSID_MSDiscMasterObj, 0, CLSCTX_ALL, IID_IDiscMaster, (void**)&idm);
idm->Open();
idm->EnumDiscRecorders(&pEnumDiscRecorders);
pEnumDiscRecorders->Next(1, &idr, &cnt);
pEnumDiscRecorders->Release();
idr->OpenExclusive();
idr->GetRecorderType(&type);
idr->QueryMediaType(&mtype, &mflags);
idr->QueryMediaInfo(&mi.nSessions, &mi.nLastTrack, &mi.nStartAddress, &mi.nNextWritable, &mi.nFreeBlocks);
idr->Release();
idm->Close();
idm->Release();
Result = true;
}
catch (...) {
Result = false;
}
if (Result == true) {
Result = false;
if (mtype == 0) {
// No Media inserted
Result = false;
}
else {
if ((mflags & 0x04) == 0x04) {
// Writable Media
Result = true;
}
else {
Result = false;
}
if (Result == true) {
*FreeSpaceSize = (mi.nFreeBlocks * 2048);
}
else {
*FreeSpaceSize = 0;
}
}
}
return Result;
}
To complement the accepted answer, we added this helper function to programatically change the burn directory on the fly as this was a requirement of ours.
typedef HMODULE (WINAPI * SHSETFOLDERPATHA)( int , HANDLE , DWORD , LPCTSTR );
int SetBurnPath( char * cpPath )
{
SHSETFOLDERPATHA pSHSetFolderPath;
HANDLE hShell = LoadLibraryA( "shell32.dll" );
if( hShell == NULL )
return -2;
DWORD dwOrdinal = 0x00000000 + 231;
pSHSetFolderPath = (SHSETFOLDERPATHA)GetProcAddress( hShell, (LPCSTR)dwOrdinal );
if( pSHSetFolderPath == NULL )
return -3;
if( pSHSetFolderPath( CSIDL_CDBURN_AREA, NULL, 0, cpPath ) == S_OK )
return 0;
return -1;
}
This is the information for IMAPI in MSDN site http://msdn.microsoft.com/en-us/library/aa939967.aspx
You should be able to use the shell's ICDBurn interface. Back in the XP day MFC didn't even have any classes for cd burning. I'll see if I can find some examples for you, but it's been a while since I looked at this.