Similar piece of code to that I recently posted as:
I have another piece of code which cannot be as easily extracted out into a method:
#define THROW_LAST_WINDOWS_ERROR()\
WindowsApi::Exception::Throw(::GetLastError(), __FILE__, __LINE__)
#define THROW_MANUAL_WINDOWS_ERROR(x)\
WindowsApi::Exception::Throw(x, __FILE__, __LINE__)
Process CreateNormalProcess(
ProcessSnapshot *parent,
const UNICODE_STRING& name,
const unsigned __int32 pid,
const std::vector<ToolHelpThread>& threads
)
{
std::wstring nameStr(name.Buffer, name.Length/sizeof(wchar_t));
std::wstring commandLine;
std::wstring mainModulePath;
std::wstring error;
std::vector<Module> modules;
try
{
using WindowsApi::Dll::NtDll;
using WindowsApi::AutoArray;
HANDLE hProc = OpenProcess(
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE,
pid);
if (hProc == 0)
{
THROW_LAST_WINDOWS_ERROR();
}
//Populate the process environment block
NtDll ntDll;
PEB peb;
AutoArray procInfoBuf = ntDll.NtQueryInformationProcess(
ProcessBasicInformation,
hProc,
sizeof(PROCESS_BASIC_INFORMATION)
);
BOOL rpmError = ReadProcessMemory(
hProc,
procInfoBuf.GetAs<PROCESS_BASIC_INFORMATION>()->PebBaseAddress,
&peb,
sizeof(peb),
0);
if (rpmError == 0)
{
THROW_LAST_WINDOWS_ERROR();
}
RTL_USER_PROCESS_PARAMETERS procParameters;
rpmError = ReadProcessMemory(hProc,
peb.ProcessParameters,
&procParameters,
sizeof(procParameters),
0);
if (rpmError == 0)
{
THROW_LAST_WINDOWS_ERROR();
}
commandLine.assign(ReadRemoteUnicodeString(hProc,
procParameters.CommandLine));
mainModulePath.assign(ReadRemoteUnicodeString(hProc,
procParameters.ImagePathName));
PEB_LDR_DATA ldrData;
rpmError = ReadProcessMemory(hProc,
peb.Ldr,
static_cast<void *>(&ldrData),
sizeof(PEB_LDR_DATA),
0);
if (rpmError == 0)
{
THROW_LAST_WINDOWS_ERROR();
}
void * endPointer = static_cast<void *>
(reinterpret_cast<char *>(peb.Ldr) + (reinterpret_cast<char *>(&ldrData.InLoadOrderModuleList) - reinterpret_cast<char *>(&ldrData)));
void * currentListEntry = ldrData.InLoadOrderModuleList.Flink;
while (currentListEntry != endPointer)
{
LDR_MODULE loaderModule;
rpmError = ReadProcessMemory(
hProc,
currentListEntry,
&loaderModule,
sizeof(loaderModule),
0);
if (rpmError == 0)
{
THROW_LAST_WINDOWS_ERROR();
}
std::wstring moduleName = ReadRemoteUnicodeString(hProc, loaderModule.FullDllName);
modules.push_back(Module(
moduleName,
loaderModule.BaseAddress,
loaderModule.SizeOfImage
));
currentListEntry = loaderModule.InLoadOrderModuleList.Flink;
}
CloseHandle(hProc);
}
catch (const ErrorAccessDeniedException&)
{
error.assign(L"ERROR: Could not access additional information because access "
L"was denied while attempting to open the process. Are you admin? Do you "
L"have SeDebugPrivilege?");
}
catch (const ErrorInvalidParameterException&)
{
error.assign(L"ERROR: The process terminated before additional information "
L"could be extracted");
}
catch (const ErrorPartialCopyException&)
{
error.assign(L"ERROR: Couldn't copy a data structure from this process. Either "
L"the process terminated before information extraction, or you are running "
L"the 32 bit version of pevFind on a 64 bit machine.");
}
if (!error.empty())
{
if (nameStr.empty())
{
nameStr = error;
}
if (commandLine.empty())
{
commandLine = error;
}
if (mainModulePath.empty())
{
mainModulePath = error;
}
}
return Process(
parent,
pid,
nameStr,
commandLine,
mainModulePath,
threads,
modules);
}
The problem here is twofold:
- I can't extract out the duplicated if blocks into a method, because it's necessary that they embed the
__FILE__
and__LINE__
. I can't put the conditional check into a macro, because the controlled method spans multiple lines:
MYMACRO( Function( Call, Spanning, Multiple, Lines));
doesn't seem to expand correctly.
if
and it's controlled block both within a single macro? \$\endgroup\$