home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 March / CMCD0304.ISO / Software / Freeware / Programare / nullsoft / nsis20.exe / Source / Plugins.cpp < prev    next >
C/C++ Source or Header  |  2004-01-30  |  4KB  |  154 lines

  1. #include "exehead/config.h"
  2. #ifdef NSIS_CONFIG_PLUGIN_SUPPORT
  3.  
  4. #include "Plugins.h"
  5. #include "Platform.h"
  6. #include <WinNT.h>
  7.  
  8.  
  9. extern FILE *g_output;
  10.  
  11. void Plugins::FindCommands(char* path,bool displayInfo)
  12. {
  13.   if (path)
  14.   {
  15.     int length = strlen(path);
  16.  
  17.     if (length > 0)
  18.     {
  19.       WIN32_FIND_DATA data;
  20.       HANDLE handle;
  21.       
  22.       if (path[length-1] == '\\' ||
  23.           path[length-1] == '/')
  24.       {
  25.         length--;
  26.       }
  27.  
  28.       char* basePath = new char [length+1];
  29.       strncpy(basePath,path,length);
  30.       basePath[length] = 0;
  31.  
  32.       char* pathAndWildcard = new char [length+7];
  33.       strcpy(pathAndWildcard,basePath);
  34.       strcat(pathAndWildcard,"\\*.dll");
  35.  
  36.       handle = FindFirstFile(pathAndWildcard,&data);
  37.       if (handle != INVALID_HANDLE_VALUE)
  38.       {
  39.         do
  40.         {
  41.           char* dllPath = new char [length+strlen(data.cFileName)+2];
  42.           wsprintf(dllPath,"%s\\%s",basePath,data.cFileName);
  43.           GetExports(dllPath,displayInfo);
  44.           delete[] dllPath;
  45.         } while (FindNextFile(handle,&data));
  46.       }
  47.  
  48.       delete[] pathAndWildcard;
  49.       delete[] basePath;
  50.     }
  51.   }
  52. }
  53.  
  54. void Plugins::GetExports(char* pathToDll,bool displayInfo)
  55. {
  56.   if (pathToDll)
  57.   {
  58.     unsigned char* dlldata    = 0;
  59.     long           dlldatalen = 0;
  60.     bool           loaded     = false;
  61.     char           dllName[100];
  62.     char           signature[256];
  63.  
  64.     dllName[0] = 0;
  65.     char* ptr = strrchr(pathToDll,'\\');
  66.     if (ptr && *ptr && *(ptr+1)) strcpy(dllName,ptr+1);
  67.     ptr = strstr(dllName, ".dll");
  68.     if (ptr) *ptr = 0;
  69.  
  70.     FILE* dll = fopen(pathToDll,"rb");
  71.     if (dll)
  72.     {
  73.       fseek(dll,0,SEEK_END);
  74.       dlldatalen = ftell(dll);
  75.       fseek(dll,0,SEEK_SET);
  76.       if (dlldatalen > 0)
  77.       {
  78.         dlldata = new unsigned char [dlldatalen];
  79.         if (dlldata)
  80.         {
  81.           size_t bytesread = fread((void*)dlldata,1,dlldatalen,dll);
  82.           if ((long)bytesread == dlldatalen)
  83.             loaded = true;
  84.         }
  85.       }
  86.       fclose(dll);
  87.     }
  88.  
  89.     if (!loaded)
  90.     {
  91.       if (dlldata) delete[] dlldata;
  92.       return;
  93.     }
  94.  
  95.     PIMAGE_NT_HEADERS NTHeaders = PIMAGE_NT_HEADERS(dlldata + PIMAGE_DOS_HEADER(dlldata)->e_lfanew);
  96.     if (NTHeaders->Signature == IMAGE_NT_SIGNATURE)
  97.     {
  98.       if (NTHeaders->FileHeader.Characteristics & IMAGE_FILE_DLL)
  99.       {
  100.         if (NTHeaders->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_EXPORT) return;
  101.  
  102.         DWORD ExportDirVA = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
  103.         DWORD ExportDirSize = NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  104.         PIMAGE_SECTION_HEADER sections = IMAGE_FIRST_SECTION(NTHeaders);
  105.  
  106.         for (int i = 0; i < NTHeaders->FileHeader.NumberOfSections; i++)
  107.           {
  108.           if (sections[i].VirtualAddress <= ExportDirVA
  109.               && sections[i].VirtualAddress+sections[i].Misc.VirtualSize >= ExportDirVA+ExportDirSize)
  110.             {
  111.             PIMAGE_EXPORT_DIRECTORY exports = PIMAGE_EXPORT_DIRECTORY(dlldata + sections[i].PointerToRawData + ExportDirVA - sections[i].VirtualAddress);
  112.             unsigned long *names = (unsigned long*)((char*)exports + exports->AddressOfNames - ExportDirVA);
  113.             for (unsigned long j = 0; j < exports->NumberOfNames; j++)
  114.             {
  115.               char *name = (char*)exports + names[j] - ExportDirVA;
  116.               wsprintf(signature, "%s::%s", dllName, name);
  117.               m_list.add(signature, pathToDll);
  118.               if (displayInfo)
  119.                 fprintf(g_output, " - %s\n", signature);
  120.             }
  121.             break;
  122.           }
  123.         }
  124.       }
  125.     }
  126.  
  127.     delete[] dlldata;
  128.   }
  129. }
  130.  
  131. bool Plugins::IsPluginCommand(char* token)
  132. {
  133.   return m_list.get(&token) ? true : false;
  134. }
  135.  
  136. char* Plugins::GetPluginDll(int uninst, char** command, int* dataHandle)
  137. {  
  138.   *dataHandle = -1;
  139.   
  140.   if (uninst)
  141.     return m_list.get(command, 0, dataHandle);
  142.   else
  143.     return m_list.get(command, dataHandle, 0);
  144. }
  145.  
  146. void Plugins::SetDllDataHandle(int uninst, char* command, int dataHandle)
  147. {
  148.   if (uninst)
  149.     m_list.setDataHandle(command, -1, dataHandle);
  150.   else
  151.     m_list.setDataHandle(command, dataHandle, -1);
  152. }
  153.  
  154. #endif