|
I actually understood your question as posted but thought 2 things:
1. I don't think there is any ways of knowing.
2. I can't think of a reason why you would want/need to know.
I thought the best you can do is determine if the dll was loaded via a static binding or a LoadLibrary() call:
http://msdn2.microsoft.com/en-us/library/ms682583.aspx[^]
lpvReserved
If fdwReason is DLL_PROCESS_ATTACH, lpvReserved is NULL for dynamic loads
and non-NULL for static loads.
If fdwReason is DLL_PROCESS_DETACH, lpvReserved is NULL if FreeLibrary
has been called or the DLL load failed and non-NULL if the process is terminating.
I can't think of a way off-hand to determine if it was an exe or other dll that was statically bound to your dll. The best i can think of is to look at the list of statically linked dll's for the exe and see if your dll is in the list, if so it was the exe, if not then another dll.
To determine if it was an exe or other dll that called LoadLibrary() to load your dll, i would walk the stack and check the address of the function that called LoadLibrary(), and from that get it's module.
I have two questions:
1. What is the scenario you have where you need to know this.
2. When can we expect an article describing how to do it.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
cmk wrote: 1. What is the scenario you have where you need to know this.
Security. We have an embedded XP system. We expose a series of APIs to third parties which allow a subset of operations depending on their contract with us. They can't, however, use the underlying DLLs of this API directly. Our concern isn't developers using the low level APIs maliciously, but as a shortcut to meet deadlines. We must keep this as light weight, non-intrusive and automated as possible for many reasons.
(Figuring out ahead of time that a DLL is being loaded statically is easy and we'll do that. It's when they load it dynamically that's more problematic.)
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Interesting.
I don't think there is a perfect solution for what you want.
e.g.
User writes an exe, the exe first loads your API dll, which then properly loads your low-level dll.
Later in the exe they load a low-level dll directly, at this point i don't think you will get a DllMain(DLL_PROCESS_ATTACH) call in the low-level dll, i just think it's ref count will be increased.
If it is to prevent 'casual' attempts then you may want to export a NONAME init function from the low-level dll that takes some cryptic params. Your API dll would then call this after loading the low-level, but before using any of it's functions. A 3rd party dev would have to hack your API dll to see what is going on. The down-side here is that the low-level functions would have to check some init flag to see if everything is ok - a little extra overhead. I've seen this method used by a number of 3rd party libraries.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
It seems that this must be done programmatically at run-time, rather than design time (which is what I'm used to with VB), but I haven't found any example code.
Does anyone have example code to changing the font color of a Static Text and Edit Control ?
thanks !
|
|
|
|
|
If you respond to the WM_CTLCOLOR message in the control's parent,
you can set the text color and background color on the passed DC.
Are you using Win32 APIs or MFC?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I am using MFC.
I've added the OnCtlColor() event and it changes the color, but the backgrounds of the edit box and static text box remain grey instead of transparent:
HBRUSH S2000_CP_DLG::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
switch ( pWnd->GetDlgCtrlID() )
{
case IDC_FW_VERSION: //Static Text box
case IDC_MESSAGES: //Edit Control
pDC->SetTextColor(rgbColor_RED);// Set the text color to red
pDC->SetBkMode(TRANSPARENT);// Set the background mode for text to transparent
break;
}
return hbr;
}
I made sure the WINVER is defined to 0x0501 to compile for XP, but still, the background is not see-through.
Is there a fix for the background transparency ?
|
|
|
|
|
You need to return a handle to a brush that you've created/obtained
instead of returning the default brush...
CBrush m_RedBrush;
...
m_RedBrush.CreateSolidBrush(RGB(0xFF,0x00,0x00));
...
HBRUSH S2000_CP_DLG::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
switch ( pWnd->GetDlgCtrlID() )
{
case IDC_FW_VERSION:
case IDC_MESSAGES:
pDC->SetTextColor(rgbColor_RED);
pDC->SetBkMode(TRANSPARENT);
break;
}
return m_RedBrush;
}
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
using the solid red brush makes the static text and edit control backgrounds red.
What I really wanted is have the bitmap on the Dialog visible through the Static Text and Edit Control.
|
|
|
|
|
You could return a NULL brush:
return (LRESULT)::GetStockObject(NULL_BRUSH);
This works on static controls, but I have not got it to work on edit controls.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I just tested - returning a NULL brush works unless XP visual styles are enabled.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes you need to respond to the WM_CTLCOLOREDIT message. Google for that and look it up on MSDN you should be able to find some code samples.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
|
|
|
|
|
Hi,
I am getting cmpilation error "Cannot convert parameter from 'int' to 'HANDLE'" on 64 bit windows for stackwalk64 code. I am porting 32 bit code to 64 bit windows. Could you please any one tell me why compiler is throwing these errors ? MS VS2005 is being used. Down below is code snippet.
stackwalkerTest.h
-----------------
typedef BOOL (__stdcall * STACKWALKPROC)
( DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID,
PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE,
PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE );
typedef DWORD (__stdcall *SYMSETOPTIONSPROC)(DWORD);
typedef BOOL (__stdcall *SYMGETSYMFROMADDRPROC)
( HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL );
typedef BOOL (__stdcall *SYMGETLINEFROMADDRPROC)
( HANDLE, DWORD, PDWORD, PIMAGEHLP_LINE );
typedef BOOL (__stdcall * SYMINITIALIZEPROC)( HANDLE, LPSTR, BOOL );
typedef BOOL (__stdcall *SYMCLEANUPPROC)( HANDLE );
typedef LPVOID (__stdcall *SYMFUNCTIONTABLEACCESSPROC)( HANDLE, DWORD );
typedef DWORD (__stdcall *SYMGETMODULEBASEPROC)( HANDLE, DWORD );
STACKWALKPROC _StackWalk64;
SYMSETOPTIONSPROC _SymSetOptions;
SYMGETSYMFROMADDRPROC _SymGetSymFromAddr;
SYMGETLINEFROMADDRPROC _SymGetLineFromAddr;
SYMINITIALIZEPROC _SymInitialize;
SYMCLEANUPPROC _SymCleanup;
SYMFUNCTIONTABLEACCESSPROC _SymFunctionTableAccess;
SYMGETMODULEBASEPROC _SymGetModuleBase;
stackwalkerTest.cpp
-------------------
_StackWalk64 = (STACKWALKPROC)::GetProcAddress(m_hImageHlp, "StackWalk64");
if ( ! _StackWalk64( IMAGE_FILE_MACHINE_AMD64,
GetCurrentProcess(),
GetCurrentThread(),
&sf,
pContext,
0,
_SymFunctionTableAccess,
_SymGetModuleBase,
0 ) )
{
....
}
Error 1 error C2664: 'BOOL
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE64,PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64,PTRANSLATE_ADDRESS_ROUTINE64)' : cannot convert parameter 2 from 'int' to 'HANDLE' d:\Work\src\Lib\Util\StackWalkerTest.cpp
Error 2 error C2664: 'BOOL
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE64,PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64,PTRANSLATE_ADDRESS_ROUTINE64)' : cannot convert parameter 3 from 'int' to 'HANDLE' d:\Work\src\Lib\Util\StackWalkerTest.cpp
Error 3 error C2664: 'BOOL
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE64,PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64,PTRANSLATE_ADDRESS_ROUTINE64)' : cannot convert parameter 5 from 'int' to 'LPVOID'
Error 4 error C2664: 'BOOL
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE64,PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64,PTRANSLATE_ADDRESS_ROUTINE64)' : cannot convert parameter 7 from 'int' to 'PFUNCTION_TABLE_ACCESS_ROUTINE64'
Error 5 error C2664: 'BOOL
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE64,PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64,PTRANSLATE_ADDRESS_ROUTINE64)' : cannot convert parameter 6 from 'int' to 'PREAD_PROCESS_MEMORY_ROUTINE64'
Error 6 error C2664: 'BOOL
(DWORD,HANDLE,HANDLE,LPSTACKFRAME64,LPVOID,PREAD_PROCESS_MEMORY_ROUTINE64,PFUNCTION_TABLE_ACCESS_ROUTINE64,PGET_MODULE_BASE_ROUTINE64,PTRANSLATE_ADDRESS_ROUTINE64)' : cannot convert parameter 4 from 'int' to 'LPSTACKFRAME64'
Any help would be highly appreciated.
Thanks in advance.
John
|
|
|
|
|
John Oliviers wrote: Cannot convert parameter from 'int' to 'HANDLE'" on 64 bit windows for stackwalk64 code
You have to use these types[^] to cast.
Maxwell Chen
|
|
|
|
|
Thanks for your reply.
I have gone through the link, there is no type to cast int to HANDLE(long *). one more thing, both function declaration and parameter are of same type HANDLE, how did the type int came into the picture.
------
typedef BOOL (__stdcall * STACKWALKPROC)
( DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID,
PREAD_PROCESS_MEMORY_ROUTINE,PFUNCTION_TABLE_ACCESS_ROUTINE,
PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE );
--------
_StackWalk64( IMAGE_FILE_MACHINE_AMD64,
GetCurrentProcess(),
GetCurrentThread(),
&sf,
pContext,
0,
_SymFunctionTableAccess,
_SymGetModuleBase,
0 )
Here 2nd parameter GetCurrentProcess() too returns HANDLE type. Then why this error occurs cannot convert parameter 2 from 'int' to 'HANDLE'
Could you please help me ?
Thanks in advance.
Thanks in advance.
John
|
|
|
|
|
Cast int to INT_PTR , then cast INT_PTR to HANDLE .
The principle is:
Under 64-bit environment, int is still 32 bits, but pointers are 64 bits.
There is alignment issue with number values...
-- modified at 14:04 Friday 24th August, 2007
Read this!
Rules for Using Pointers (64-bit Computing, MSDN)[^].
Maxwell Chen
|
|
|
|
|
Modified as HANDLE(INT_PTR(GetCurrentProcess())) but still getting compilation error that cannot convert int to HANDLE.
Thanks in advance.
John
|
|
|
|
|
Hmm... I don't have 64-bit compiler at home, otherwise I could give you a working code snippet...
Maxwell Chen
|
|
|
|
|
Just curious to know that why casting required on return value of GetCurrentProcess()?
GetCurrentProcess return value is HANDLE. I have some knowledge about 64 bit windows that int,long are 32 bit size whereas pointer is of size 64 bit, so casting is required between int,long to pointer and vice versa.
Why do you we need casting on this case ?
I really appreciate your helping tendency and your time.
Thanks in advance.
John
|
|
|
|
|
Yeah... HANDLE should also have been typedef ed...
Maxwell Chen
|
|
|
|
|
Yeah. It has been typedef as long*. But still no need for casting. Right?
Thanks in advance.
John
|
|
|
|
|
Wait...
Could you use [Go to definition], and paste the code snippet for
#ifdef AMD64 // Or x64 something
typedef PVOID HANDLE;
#else // WIN32
#endif
Maxwell Chen
|
|
|
|
|
Hi,
Previously suggestion is also not working. I still got stuck with compilation error.
Any suggestion would be highly appreciated.
Thanks in advance.
Thanks in advance.
John
|
|
|
|
|
I am at office now. I just copied your code snippet and compiled with VC++2005 Pro in x64 mode. It compiles without errors.
typedef BOOL (__stdcall * STACKWALKPROC)
( DWORD, HANDLE, HANDLE );
void main(int argc, char *argv[])
{
STACKWALKPROC _StackWalk64;
_StackWalk64 = (STACKWALKPROC)::GetProcAddress(NULL, "StackWalk64");
1>------ Build started: Project: KeyFD, Configuration: Release x64 ------
1>Compiling...
1>main.cpp
1>Linking...
1>Generating code
1>Finished generating code
1>Embedding manifest...
1>Build log was saved at "file://e:\Wrkshp\KeyFD\x64\Release\BuildLog.htm"
1>KeyFD - 0 error(s), 0 warning(s)
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
Maxwell Chen
|
|
|
|
|
Hi,
I have a win 32 console application which will spawn a telnet window (Telnet.exe -l username) by using CreateProcess() API call and then pass the password (read from a file by the parent process) to the child process (Telnet window) using anonymous pipes. I have tried with the following code which i got from MSDN and partially modified , but could not get the result.
Please help me how can i pass data to telnet window so that it will logon automatically.
#include <stdio.h>
#include <windows.h>
#define BUFSIZE 4096
HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
hInputFile, hStdout, hStdInput,hProcess;
PROCESS_INFORMATION piProcInfo;
BOOL CreateChildProcess(VOID);
VOID WriteToPipe(VOID);
VOID ReadFromPipe(VOID);
VOID ErrorExit(LPTSTR);
VOID ErrMsg(LPTSTR, BOOL);
DWORD main(int argc, char *argv[])
{
SECURITY_ATTRIBUTES saAttr;
BOOL fSuccess;
// Set the bInheritHandle flag so pipe handles are inherited.
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Get the handle to the current STDOUT.
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
hStdInput = GetStdHandle(STD_INPUT_HANDLE);
// Create a pipe for the child process's STDOUT.
if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
ErrorExit("Stdout pipe creation failed\n");
// Create noninheritable read handle and close the inheritable read
// handle.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
GetCurrentProcess(), &hChildStdoutRdDup , DUPLICATE_SAME_ACCESS,
FALSE,
DUPLICATE_SAME_ACCESS);
if( !fSuccess )
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdoutRd);
// Create a pipe for the child process's STDIN.
if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
ErrorExit("Stdin pipe creation failed\n");
// Duplicate the write handle to the pipe so it is not inherited.
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
GetCurrentProcess(), &hChildStdinWrDup, DUPLICATE_SAME_ACCESS,
FALSE, // not inherited
DUPLICATE_SAME_ACCESS);
if (! fSuccess)
ErrorExit("DuplicateHandle failed");
CloseHandle(hChildStdinWr);
// Now create the child process.
fSuccess = CreateChildProcess();
if (! fSuccess)
ErrorExit("Create process failed");
// Get a handle to the parent's input file.
if (argc == 1)
ErrorExit("Please specify an input file");
hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
if (hInputFile == INVALID_HANDLE_VALUE)
ErrorExit("CreateFile failed\n");
// Write to pipe that is the standard input for a child process.
WriteToPipe();
// Read from pipe that is the standard output for child process.
// ReadFromPipe();
hProcess = piProcInfo.hProcess;
WaitForSingleObject(hProcess,INFINITE);
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);
return 0;
}
BOOL CreateChildProcess()
{
STARTUPINFO siStartInfo;
BOOL bFuncRetn = FALSE;
const char* lpAppName ="C:\\Windows\\System32\\Telnet.exe";
char* lpCmd = "open 10.41.37.239 -l guest";
// Set up members of the PROCESS_INFORMATION structure.
ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
// Set up members of the STARTUPINFO structure.
ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = hChildStdoutRdDup;
siStartInfo.hStdOutput = hChildStdoutRdDup;
siStartInfo.hStdInput = hChildStdinWrDup;
// Create the child process.
bFuncRetn = CreateProcess(lpAppName,
lpCmd, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
CREATE_NEW_CONSOLE, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
if (bFuncRetn == 0)
{
ErrorExit("CreateProcess failed");
}
else
{
//CloseHandle(piProcInfo.hProcess);
//CloseHandle(piProcInfo.hThread);
return bFuncRetn;
}
return 0;
}
VOID WriteToPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
memset(chBuf,0,BUFSIZE);
// Read from a file and write its contents to a pipe.
ReadFile(hInputFile, chBuf, BUFSIZE, &dwRead, NULL);
WriteFile(hStdInput, chBuf, dwRead, &dwWritten, NULL);
// Close the pipe handle so the child process stops reading.
if (! CloseHandle(hChildStdinWrDup))
ErrorExit("Close pipe failed");
}
VOID ReadFromPipe(VOID)
{
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
memset(chBuf,0,BUFSIZE);
// Close the write end of the pipe before reading from the
// read end of the pipe.
if (!CloseHandle(hChildStdoutWr))
ErrorExit("CloseHandle failed");
// Read output from the child process, and write to parent's STDOUT.
ReadFile( hChildStdoutRdDup, chBuf, BUFSIZE, &dwRead,
NULL);
WriteFile(hStdout, chBuf, dwRead, &dwWritten, NULL);
}
VOID ErrorExit (LPTSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}
Thanks in advance.
Best Regards
Viswa
Visweswara Koduri
|
|
|
|
|
Hi, I'm developing a Windows Application with MFC and C++. I've added to the solution a Visual Studio Setup Project and it's installing everything ok. The problem is that now I want to configure the installer so it sets some permissions (I need "everyone full control") in my application folder, inside "Program Files", and I don't find how to do it.
I would really appreciate any clue that could help me to solve this problem.
Thanks!
Federico
PS: I'm using Visual Studio .NET 2003
|
|
|
|
|