RE: accessing m_lpCmdLine (or GetCommandLine())
Here is my stub code.
// simple macro to handle errors
#define SIGNAL_ERROR() { bError = TRUE; __leave; }
// align pointer
#define ALIGN_DWORD(x) ( (x & 0xFFFFFFFC) ? (x & 0xFFFFFFFC) + sizeof(DWORD)
: x )
#define BLOCK_ADDRESS (LPVOID)0x00020498
BOOL GetProcessCmdLine(HANDLE hProcess, LPWSTR lpszCmdLine)
{
LPBYTE lpBuffer = NULL;
LPBYTE lpPos = NULL; // offset from the start of the buffer
DWORD dwBytesRead;
MEMORY_BASIC_INFORMATION mbi;
SYSTEM_INFO sysinfo;
BOOL bError = FALSE;
__try {
// Get the system page size by using GetSystemInfo()
GetSystemInfo ( &sysinfo );
// allocate one on the heap to retrieve a full page
// of memory
lpBuffer = (LPBYTE)malloc ( sysinfo.dwPageSize );
if ( lpBuffer == NULL )
SIGNAL_ERROR ();
// first of all, use VirtualQuery to get the start of the memory
// block
if ( VirtualQueryEx ( hProcess, BLOCK_ADDRESS, &mbi, sizeof(mbi) ) == 0 )
SIGNAL_ERROR ();
// read memory begining at the start of the page
// after that, we know that the env strings block
// will be 0x498 bytes after the start of the page
if ( !ReadProcessMemory ( hProcess, mbi.BaseAddress, (LPVOID)lpBuffer,
sysinfo.dwPageSize, &dwBytesRead ) )
SIGNAL_ERROR ();
// now we've got the buffer on our side of the fence.
// first, lpPos points to a string containing the current directory
/// plus the path.
lpPos = lpBuffer + ((DWORD)BLOCK_ADDRESS - (DWORD)mbi.BaseAddress);
lpPos = lpPos + ( GetUnicodeStringLength((LPWSTR)lpPos, MAX_PATH ) + 1) *
sizeof(WCHAR);
// now goes full path an filename, aligned on a DWORD boundary
// skip it
lpPos = (LPBYTE)ALIGN_DWORD((DWORD)lpPos);
lpPos = lpPos + (GetUnicodeStringLength((LPWSTR)lpPos, MAX_PATH) + 1) *
sizeof(WCHAR);
// hack: Sometimes, there will be another '\0' at this position
// if that's so, skip it
if ( *lpPos == '\0' ) lpPos += sizeof(WCHAR);
// now we have the actual command line
// copy it to the buffer
wcsncpy ( lpszCmdLine, (LPWSTR)lpPos, MAX_PATH);
// make sure the path is null-terminted
lpszCmdLine[MAX_PATH-1] = L'\0';
}
__finally {
// clean up
if ( lpBuffer != NULL ) free ( lpBuffer );
#ifdef VERIFYMODE
printf("GetProcessCmdLine Result : %d\n", bError ? FALSE : TRUE);
#endif
return bError ? FALSE : TRUE;
}
}
--
WebSite :
Realization of Dream { imagine your dream} - http://rodream.net
WebMail :
rodream@naver.com
"Mark Grinnell" wrote:
We have an MFC application that was converted to run as a DLL extension to
another program. Instead of an MFC main loop we are using
AFX_MANAGE_STATE(AfxGetStaticModuleState());
to hook up our MFC code to the new app. The problem is that now
AfxGetApp()->m_lpCmdLine
does not have the command line any more, just an empty string.
Additionally (and I posted this part to win32.programmer.kernel as well)
GetCommandLine() is not returning the command line string either -- instead,
we get a buffer with each (incorrectly parsed) argument followed by a null
terminator, and the last argument followed by a double null terminator.
Any suggestions for getting the real command line, as we used to get in
m_lpCmdLine?