2 #include "plain/PluginImplPlain.h"
5 # include "elf/PluginImplELF.h"
12 SHAREDSYMBOL
void PluginModuleOpen(const char *path
)
15 // fprintf(stderr, "Inside::PluginModuleOpen\n");
18 SHAREDSYMBOL
int WINAPI _export
GetMinFarVersion(void)
20 #define MAKEFARVERSION(major,minor) ( ((major)<<16) | (minor))
21 return MAKEFARVERSION(2, 1);
25 SHAREDSYMBOL
void WINAPI _export
SetStartupInfo(const struct PluginStartupInfo
*Info
)
28 // fprintf(stderr, "Inside::SetStartupInfo\n");
31 #define MINIMAL_LEN 0x34
33 static bool HasElvenEars(const unsigned char *Data
, int DataSize
)
36 //FAR reads at least 0x1000 bytes if possible, so may assume full ELF header available if its there
37 if (DataSize
< MINIMAL_LEN
|| Data
[0] != 0x7F || Data
[1] != 'E'|| Data
[2] != 'L'|| Data
[3] != 'F')
39 if (Data
[4] != 1 && Data
[4] != 2) // Bitness: 32/64
41 if (Data
[5] != 0 && Data
[5] != 1 && Data
[5] != 2) // Endianess: None(?)/LSB/MSB
43 if (Data
[6] != 1) // Version: 1
52 static const char *DetectPlainKind(const char *Name
, const unsigned char *Data
, int DataSize
)
54 const char *ext
= Name
? strrchr(Name
, '.') : nullptr;
56 if (DataSize
>= 8 && Data
[0] == '%' && Data
[1] == 'P' && Data
[2] == 'D' && Data
[3] == 'F' &&
57 Data
[4] == '-' && Data
[5] >= '0' && Data
[5] <= '9' && Data
[6] == '.' && Data
[7] >= '0' && Data
[7] <= '9') {
60 } else if (DataSize
>= 8 && Data
[0] == 0xd0 && Data
[1] == 0xcf && Data
[2] == 0x11 && Data
[3] == 0xE0 &&
61 Data
[4] == 0xA1 && Data
[5] == 0xB1 && Data
[6] == 0x1A && Data
[7] == 0xE1) {
62 if (!ext
|| strcasecmp(ext
, ".doc") == 0) { // disinct from excel/ppt etc
66 if (strcasecmp(ext
, ".ppt") == 0) {
70 if (strcasecmp(ext
, ".xls") == 0) {
74 } else if (DataSize
>= 8 && Data
[0] == '{' && Data
[1] == '\\' && Data
[2] == 'r' && Data
[3] == 't' && Data
[4] == 'f'
75 && ext
&& strcasecmp(ext
, ".rtf") == 0) { // ensure
78 } else if (DataSize
>= 8 && Data
[0] == 0xff && Data
[1] == 0xd8 && Data
[2] == 0xff
79 && ext
&& (strcasecmp(ext
, ".jpg") == 0 || strcasecmp(ext
, ".jpeg") == 0)) {
82 } else if (DataSize
>= 8 && Data
[0] == 'A' && Data
[1] == 'T' && Data
[2] == '&' && Data
[3] == 'T'
83 && Data
[4] == 'F' && Data
[5] == 'O' && Data
[6] == 'R' && Data
[7] == 'M'
84 && ext
&& strcasecmp(ext
, ".djvu") == 0) { // Ensure
88 } else if (DataSize
>= 8 && ext
&& strcasecmp(ext
, ".mp3") == 0) {
91 } else if (DataSize
>= 8 && Data
[0] == 'M' && Data
[1] == 'A' && Data
[2] == 'C'
92 && ext
&& strcasecmp(ext
, ".ape") == 0) {
95 } else if (DataSize
>= 8 && Data
[0] == 'w' && Data
[1] == 'v' && Data
[2] == 'p' && Data
[3] == 'k'
96 && ext
&& strcasecmp(ext
, ".vw") == 0) {
99 } else if (DataSize
>= 8 && Data
[0] == 'f' && Data
[1] == 'L' && Data
[2] == 'a' && Data
[3] == 'C'
100 && ext
&& strcasecmp(ext
, ".flac") == 0) {
108 SHAREDSYMBOL HANDLE WINAPI _export
OpenFilePlugin(const char *Name
, const unsigned char *Data
, int DataSize
, int OpMode
)
111 return INVALID_HANDLE_VALUE
;
113 const bool elf
= HasElvenEars(Data
, DataSize
);
114 const char *plain
= elf
? nullptr : DetectPlainKind(Name
, Data
, DataSize
);
116 // fprintf(stderr, "Inside: OpenFilePlugin('%s' .. 0x%x): %s %s\n", Name, OpMode, elf ? "ELF" : "", plain ? plain : "");
119 return INVALID_HANDLE_VALUE
;
121 // Well, it really looks like valid ELF or some plain document file
123 if ( (OpMode
& OPM_FIND
) != 0) {
124 // In case of open from find file dialog - allow digging into plain document files,
125 // but not ELFs - there is nothing interesting to search inside of disasm etc.
127 return INVALID_HANDLE_VALUE
;
129 } else if ((OpMode
& (OPM_PGDN
| OPM_COMMANDS
)) == 0) {
130 // If user called us with Ctrl+PgDn - then proceed for any file
131 // Otherwise proceed only for ELF file and only if its not eXecutable, to allow user execute it by Enter
133 return INVALID_HANDLE_VALUE
;
136 if (sdc_stat(Name
, &s
) == -1) // in case of any uncertainlity...
137 return INVALID_HANDLE_VALUE
;
139 if ((s
.st_mode
& (S_IXUSR
| S_IXGRP
| S_IXOTH
)) != 0)
140 return INVALID_HANDLE_VALUE
;
143 PluginImpl
*out
= nullptr;
146 out
= new PluginImplELF(Name
, Data
[4], Data
[5]);
151 out
= new PluginImplPlain(Name
, plain
);
156 return out
? (HANDLE
)out
: INVALID_HANDLE_VALUE
;
160 SHAREDSYMBOL HANDLE WINAPI _export
OpenPlugin(int OpenFrom
, INT_PTR Item
)
162 if (!G
.IsStarted() || OpenFrom
!= OPEN_COMMANDLINE
)
163 return INVALID_HANDLE_VALUE
;
165 if (strncmp((const char *)Item
, G
.command_prefix
.c_str(), G
.command_prefix
.size()) != 0
166 || ((const char *)Item
)[G
.command_prefix
.size()] != ':') {
167 return INVALID_HANDLE_VALUE
;
170 std::string
path( &((const char *)Item
)[G
.command_prefix
.size() + 1] );
171 if (path
.size() >1 && path
[0] == '\"' && path
[path
.size() - 1] == '\"')
172 path
= path
.substr(1, path
.size() - 2);
174 return INVALID_HANDLE_VALUE
;
176 int fd
= sdc_open(path
.c_str(), O_RDONLY
);
178 return INVALID_HANDLE_VALUE
;
180 unsigned char data
[MINIMAL_LEN
];
181 int data_len
= sdc_read(fd
, data
, sizeof(data
));
183 return OpenFilePlugin(path
.c_str(), data
, data_len
, OPM_COMMANDS
);
186 SHAREDSYMBOL
void WINAPI _export
ClosePlugin(HANDLE hPlugin
)
188 delete (PluginImpl
*)hPlugin
;
192 SHAREDSYMBOL
int WINAPI _export
GetFindData(HANDLE hPlugin
,struct PluginPanelItem
**pPanelItem
,int *pItemsNumber
,int OpMode
)
194 return ((PluginImpl
*)hPlugin
)->GetFindData(pPanelItem
, pItemsNumber
, OpMode
);
198 SHAREDSYMBOL
void WINAPI _export
FreeFindData(HANDLE hPlugin
,struct PluginPanelItem
*PanelItem
,int ItemsNumber
)
200 ((PluginImpl
*)hPlugin
)->FreeFindData(PanelItem
, ItemsNumber
);
204 SHAREDSYMBOL
int WINAPI _export
SetDirectory(HANDLE hPlugin
,const char *Dir
,int OpMode
)
206 return ((PluginImpl
*)hPlugin
)->SetDirectory(Dir
, OpMode
);
210 SHAREDSYMBOL
int WINAPI _export
DeleteFiles(HANDLE hPlugin
,struct PluginPanelItem
*PanelItem
,int ItemsNumber
,int OpMode
)
212 return ((PluginImpl
*)hPlugin
)->DeleteFiles(PanelItem
, ItemsNumber
, OpMode
);
216 SHAREDSYMBOL
int WINAPI _export
GetFiles(HANDLE hPlugin
,struct PluginPanelItem
*PanelItem
,
217 int ItemsNumber
,int Move
,char *DestPath
,int OpMode
)
219 return ((PluginImpl
*)hPlugin
)->GetFiles(PanelItem
, ItemsNumber
, Move
, DestPath
, OpMode
);
223 SHAREDSYMBOL
int WINAPI _export
PutFiles(HANDLE hPlugin
,struct PluginPanelItem
*PanelItem
,
224 int ItemsNumber
,int Move
,int OpMode
)
226 return ((PluginImpl
*)hPlugin
)->PutFiles(PanelItem
, ItemsNumber
, Move
, OpMode
);
230 SHAREDSYMBOL
void WINAPI _export
ExitFAR()
235 SHAREDSYMBOL
void WINAPI _export
GetPluginInfo(struct PluginInfo
*Info
)
237 Info
->StructSize
= sizeof(*Info
);
239 Info
->Flags
= PF_FULLCMDLINE
;
240 static const char *PluginCfgStrings
[1];
241 PluginCfgStrings
[0] = (char*)G
.GetMsg(MTitle
);
242 Info
->PluginConfigStrings
= PluginCfgStrings
;
243 Info
->PluginConfigStringsNumber
= ARRAYSIZE(PluginCfgStrings
);
245 static char s_command_prefix
[G
.MAX_COMMAND_PREFIX
+ 1] = {}; // WHY?
246 strncpy(s_command_prefix
, G
.command_prefix
.c_str(), sizeof(s_command_prefix
));
247 Info
->CommandPrefix
= s_command_prefix
;
250 SHAREDSYMBOL
void WINAPI _export
GetOpenPluginInfo(HANDLE hPlugin
,struct OpenPluginInfo
*Info
)
252 ((PluginImpl
*)hPlugin
)->GetOpenPluginInfo(Info
);
255 SHAREDSYMBOL
int WINAPI _export
ProcessHostFile(HANDLE hPlugin
,struct PluginPanelItem
*PanelItem
,int ItemsNumber
,int OpMode
)
257 return ((PluginImpl
*)hPlugin
)->ProcessHostFile(PanelItem
, ItemsNumber
, OpMode
);
260 SHAREDSYMBOL
int WINAPI _export
ProcessKey(HANDLE hPlugin
,int Key
,unsigned int ControlState
)
262 return ((PluginImpl
*)hPlugin
)->ProcessKey(Key
, ControlState
);
265 SHAREDSYMBOL
int WINAPI _export
Configure(int ItemNumber
)
270 struct FarDialogItem fdi
[] = {
271 {DI_DOUBLEBOX
, 3, 1, 70, 5, 0, {}, 0, 0, {}},
272 {DI_TEXT
, -1, 2, 0, 2, 0, {}, 0, 0, {}},
273 {DI_BUTTON
, 0, 4, 0, 4, 0, {}, DIF_CENTERGROUP
, 0, {}},
274 {DI_BUTTON
, 0, 4, 0, 4, 0, {}, DIF_CENTERGROUP
, 0, {}}
277 ArrayCpyZ(fdi
[0].Data
, G
.GetMsg(MTitle
));
278 ArrayCpyZ(fdi
[1].Data
, G
.GetMsg(MDescription
));
279 ArrayCpyZ(fdi
[2].Data
, G
.GetMsg(MOK
));
280 ArrayCpyZ(fdi
[3].Data
, G
.GetMsg(MCleanup
));
282 if (G
.info
.Dialog(G
.info
.ModuleNumber
, -1, -1, 74, 7, NULL
, fdi
, ARRAYSIZE(fdi
)) == 3) {