root/trunk/nt/fiber.c

Revision 3777, 28.5 kB (checked in by miyoshi, 3 years ago)

* RunMW32.c: Normalize coding style and remove redundant spaces.

* RunMW32.c: Ditto.

* fakecygpty.c: Ditto.

* fiber.c: Ditto.

* install.c: Ditto.

* ChangeLog?.Meadow: Ditto.

  • Property svn:eol-style set to native
Line 
1 /*
2  * File Inspect and Broking End Resolver  -- fiber --
3  *
4  *       Copyright (C) 1997-2004  Shuichi Kitaguchi <kit@meadowy.org>
5  *
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either versions 2, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with fiber, see the file COPYING.  If not, write to the Free
19  * Software Foundation Inc., 59 Temple Place - Suite 330, Boston,
20  * MA 02111-1307, USA.
21  */
22
23 /*
24  * HISTORY
25  * -------
26  *
27  *    01 Feb, 1998 : Version 1.0.0 - first release.
28  *    13 Jun, 1998 : Version 1.1.0 - if registry key is not found, write init values.
29  *                                   add "-s" optoin.
30  *                                   WriteRegistry bug fix.
31  *                                   add "-o" option.
32  *    23 Jun, 1998 : Version 1.1.1 - show options with "-l".
33  *                                   remove copied file when "-s" mode.
34  *                                   do not delete "foo.ext" when execute "fiber foo"
35  *                                   and "foo.ext" exists.
36  *    27 Jun, 1998 : Version 1.1.2 - add SEE_MASK_FLAG_DDEWAIT flag in
37  *                                   ShellExecuteOpenSync.
38  *    29 Jun, 1998 : Version 1.1.3 - use ShellExecuteEx if not sync mode.
39  *    19 Jul, 1999 : Version 1.1.4 - add "-p" and "-n" option.
40  *                                   "ExecuteUnknownExt=yes" is default.
41  *    07 Aug, 1999 : Version 1.2.0 - add "-b" and "-d" option.
42  *    05 Oct, 1999 : Version 1.2.1 - brush up English text.
43  *    12 Jan, 2004 : Version 1.2.2 - convert path name to full path name before
44  *                                   executing files.
45  *                                 - eliminate "file:" scheme.
46  *    18 Jan, 2004 : Version 1.2.3 - DO NOT eliminate "file:" scheme.
47  */
48
49
50 #include <windows.h>
51 #include <shellapi.h>
52 #include <stdio.h>
53 #include <limits.h>
54 #include <mbstring.h>
55
56
57 #define FIBER_VERSION   "1.2.3"
58
59
60 /* constants */
61 #define FIBER_EXTNUM     64     /* default extension numbers */
62 #define FIBER_EXTLEN     8      /* extension length */
63 #define FIBER_OPTIONLEN  64     /* option length */
64 #define FIBER_IDENTLEN   32     /* ident length */
65 #define BUFLEN           4096   /* buffer */
66 #define FIBER_EXTLINELEN (FIBER_EXTLEN+FIBER_IDENTLEN+3)        /* line len */
67
68 #define STATE_ERROR     0
69 #define STATE_INPUTFILE 1
70 #define STATE_ADDEXT    2
71
72 /* registry keys */
73 #define FIBER_SUBKEY                    "SOFTWARE\\GNU\\Fiber"
74 #define FIBER_SUBKEY_EXTNUM             "ExtNum"
75 #define FIBER_SUBKEY_EXECUTEUNKNOWNEXT  "ExecuteUnknownExt"
76 #define FIBER_SUBKEY_EXECUTEURL         "ExecuteURL"
77 #define FIBER_SUBKEY_TRUSTEXT           "TrustExt"
78 #define FIBER_SUBKEY_OVERRIDEEXT        "OverrideExt"
79 #define FIBER_SUBKEY_EXTENSION          "Extension"
80
81
82 /* structures */
83 typedef struct tagEXTFILE
84 {
85   char szExt[FIBER_EXTLEN + 1];
86   char szIdent[FIBER_IDENTLEN + 1];
87   DWORD dwIdentLength;
88   DWORD dwOffset;
89 } EXTFILE;
90
91
92 /* variables */
93 EXTFILE *ef = NULL;
94 int iExtNum = 0;
95 int iEfs = 0;
96 BOOL fExecuteUnknownExt;
97 BOOL fExecuteURL;
98 BOOL fTrustExt;
99 BOOL fOverrideExt;
100
101 /* default ext values */
102 EXTFILE efInit[] = {
103   {"au", ".snd", 4, 0},
104   {"wav", "WAVE", 4, 8},
105   {"mid", "MThd", 4, 0},
106   {"rcp", "RCM-PC98V2.0", 12, 0},
107   {"mov", "moov", 4, 4},
108   {"avi", "AVI", 3, 8},
109   {"mpg", "\x00\x00\x01\xb3", 4, 0},
110   {"jpg", "JFIF", 4, 134},
111   {"jpg", "JFIF", 4, 6},
112   {"bmp", "BM", 2, 0},
113   {"gif", "GIF8", 4, 0},
114   {"xpm", "XPM", 3, 3},
115   {"tif", "MM", 2, 0},
116   {"tif", "II", 2, 0},
117   {"mki", "MAKI01", 6, 0},
118   {"mag", "MAKI02", 6, 0},
119   {"pic", "PIC", 3, 0},
120   {"pi", "Pi", 2, 0},
121   {"p2", "P2", 2, 0},
122   {"png", "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8, 0},
123   {"pdf", "%PDF-", 5, 0},
124   {"ps", "%!", 2, 0},
125   {"dvi", "\xf7\x02", 2, 0},
126   {"zip", "PK", 2, 0},
127   {"gz", "\x1f\x8b", 2, 0},
128   {"lzh", "SFX", 3, 0x48},
129   {"lzh", "SFX", 3, 0x2e},
130   {"lzh", "SFX", 3, 0x2a},
131   {"lzh", "-lhd-", 4, 2},
132   {"lzh", "-lh0-", 4, 2},
133   {"lzh", "-lh1-", 4, 2},
134   {"lzh", "-lh2-", 4, 2},
135   {"lzh", "-lh3-", 4, 2},
136   {"lzh", "-lh4-", 4, 2},
137   {"lzh", "-lh5-", 4, 2},
138   {"lzh", "-lh6-", 4, 2},
139   {"lzh", "-lh7-", 4, 2},
140   {"zoo", "ZOO", 3, 0},
141   {"", "", 0, 0}
142 };
143
144
145
146 /* check file existing */
147 BOOL
148 CheckFile (LPCSTR lpszFileName)
149 {
150   HANDLE hFile;
151
152   hFile = CreateFile (lpszFileName,
153                       GENERIC_READ,
154                       FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
155   if (hFile == INVALID_HANDLE_VALUE)
156     {
157       return (FALSE);
158     }
159   else
160     {
161       CloseHandle (hFile);
162       return (TRUE);
163     }
164 }
165
166
167 /* '/' -> '\' */
168 BOOL
169 RevConvertPathSeparator (LPSTR szPathName)
170 {
171   char *pt;
172
173   while (1)
174     {
175       pt = _mbsrchr (szPathName, '/');
176       if (pt == NULL)
177         break;
178       *pt = '\\';
179     }                           /* while ( 1 ){ */
180
181   return (TRUE);
182 }
183
184
185 BOOL
186 GetFileNameFromFullPath (LPCSTR szFullPath, LPSTR lpBuf, DWORD dwLength)
187 {
188   char *pt;
189   DWORD dwLen;
190
191   pt = _mbsrchr (szFullPath, '\\');
192   if (pt)
193     {
194       dwLen = strlen (pt) + 1;
195       pt++;
196     }
197   else
198     {
199       dwLen = strlen (szFullPath) + 1;
200       pt = (char *) szFullPath;
201     }                           /* if ( pt ){ */
202   if (dwLen <= dwLength)
203     {
204       memcpy (lpBuf, pt, dwLen);
205       return (TRUE);
206     }
207   else
208     {
209       return (FALSE);
210     }                           /* if ( dwLen <= dwLength ){ */
211 }
212
213
214 BOOL
215 BinaryToHexString (LPCSTR szString, DWORD dwLen, LPSTR lpBuf, DWORD dwBufLen)
216 {
217   DWORD i;
218   char szBuf[8];
219
220   if (dwBufLen < dwLen * 4)
221     return (FALSE);
222   lpBuf[0] = 0;
223   for (i = 0; i < dwLen; i++)
224     {
225       sprintf (szBuf, "0x%02x", (BYTE) szString[i]);
226       strcat (lpBuf, szBuf);
227     }
228   return (TRUE);
229 }
230
231
232 /* string -> value */
233 BOOL
234 CStringToValue (LPCSTR szSrc, LPDWORD lpdwDst)
235 {
236   BOOL ret;
237   LPSTR pt;
238
239   if (szSrc[0] == '0')
240     {
241       switch (szSrc[1])
242         {
243         case 'x':               /* hex */
244           *lpdwDst = 0;
245           pt = (LPSTR) & szSrc[2];
246           while (*pt)
247             {
248               if ((*pt >= '0') && (*pt <= '9'))
249                 {
250                   *lpdwDst = *lpdwDst * 16 + *pt - '0';
251                 }
252               else if ((*pt >= 'A') && (*pt <= 'F'))
253                 {
254                   *lpdwDst = *lpdwDst * 16 + *pt - 'A' + 10;
255                 }
256               else
257                 {
258                   *lpdwDst = *lpdwDst * 16 + *pt - 'a' + 10;
259                 }
260               pt++;
261             }                   /* while ( *pt ){ */
262           ret = TRUE;
263           break;
264         case 'b':               /* bin */
265           *lpdwDst = 0;
266           pt = (LPSTR) & szSrc[2];
267           while (*pt)
268             {
269               *lpdwDst = *lpdwDst * 2 + *pt - '0';
270               pt++;
271             }
272           ret = TRUE;
273           break;
274         default:
275           if ((szSrc[1] >= '0') && (szSrc[1] <= '9'))
276             {                   /* oct */
277               *lpdwDst = 0;
278               pt = (LPSTR) & szSrc[1];
279               while (*pt)
280                 {
281                   *lpdwDst = *lpdwDst * 8 + *pt - '0';
282                   pt++;
283                 }
284               ret = TRUE;
285             }
286           else
287             {                   /* error */
288               ret = FALSE;
289             }
290           break;
291         }
292     }
293   else
294     {
295       /* dec */
296       *lpdwDst = atol (szSrc);
297       if (*lpdwDst == 0)
298         {
299           ret = FALSE;
300         }
301       else
302         {
303           ret = TRUE;
304         }
305     }                           /* if ( szSrc[0] == '0' ){ */
306   return (ret);
307 }
308
309 /* 0x**0x**... */
310 DWORD
311 HexStringToBinary (LPCSTR szSrc, LPSTR szDst, DWORD dwLen)
312 {
313   char szBuf[FIBER_IDENTLEN + 1];
314   char *spt, *dpt;
315   DWORD dwRet;
316   DWORD dwV;
317
318   if (strlen (szSrc) > FIBER_IDENTLEN)
319     return (0);
320
321   dwRet = 0;
322   spt = (LPSTR) szSrc;
323   dpt = szDst;
324   while (*spt)
325     {
326       memcpy (szBuf, spt, 4);   /* xxx */
327       szBuf[4] = 0;
328       CStringToValue (szBuf, &dwV);
329       *dpt++ = (char) dwV;
330       dwRet++;
331       spt += 4;
332       if (dwRet > dwLen)
333         break;
334     }                           /* while ( *spt ){ */
335
336   return (dwRet);
337 }
338
339
340 BOOL
341 SetEf (EXTFILE * ef, LPCSTR lpLine)
342 {
343   char *pt, *ppt;
344   BOOL ret = FALSE;
345
346   if ((pt = _mbschr (lpLine, '=')) != NULL)
347     {
348       *pt++ = (char) 0;
349       if (strlen (lpLine) <= FIBER_EXTLINELEN)
350         {
351           strcpy (ef->szExt, lpLine);
352           if ((ppt = strchr (pt, ',')) != NULL)
353             {
354               *ppt++ = (char) 0;
355               if (!CStringToValue (ppt, &ef->dwOffset))
356                 {
357                   printf ("Error: illegal offset value.\n");
358                   goto Exit;
359                 }
360             }
361           else
362             {
363               ef->dwOffset = 0;
364             }                   /* if ( (ppt=strchr(pt,',')) != NULL ){ */
365           if (strlen (pt) <= FIBER_IDENTLEN)
366             {
367               if (*pt == '0')
368                 {
369                   ef->dwIdentLength =
370                     HexStringToBinary (pt, ef->szIdent, sizeof (ef->szIdent));
371                 }
372               else
373                 {
374                   strcpy (ef->szIdent, pt);
375                   ef->dwIdentLength = strlen (ef->szIdent);
376                 }
377               ret = TRUE;
378             }
379           else
380             {
381               printf ("Error: ident [%s] is too long.\n", pt);
382             }                   /* if ( strlen(pt) <= FIBER_IDENTLEN ){ */
383         }
384       else
385         {
386           printf ("Error: ext [%s] is too long.\n", pt);
387         }                       /* if ( strlen(lpLine) <= FIBER_EXTLINELEN ){ */
388     }                           /* if ( (pt=_mbschr(lpLine,'=')) != NULL ){ */
389 Exit:
390   if (!ret)
391     ef->szExt[0] = 0;
392   return (ret);
393 }
394
395
396 BOOL
397 WriteRegistry (VOID)
398 {
399   DWORD ret;
400   HKEY hKey;
401   char szBuf[256];
402   char szIdent[FIBER_IDENTLEN * 4 + 1];
403   char szSubKey[256];
404   BOOL fRet = TRUE;
405   int i, c;
406   DWORD dwDisposition;
407   char *pt;
408
409   ret = RegCreateKeyEx (HKEY_LOCAL_MACHINE,
410                         FIBER_SUBKEY,
411                         0,
412                         "",
413                         0, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisposition);
414   if (ret != ERROR_SUCCESS)
415     {
416       printf ("Error: cannot open registry.\n");
417       return (FALSE);
418     }
419
420   c = 0;
421   for (i = 0; i < iEfs; i++)
422     {
423       if (ef[i].szExt[0] != 0)
424         {
425           sprintf (szSubKey, "%s%d", FIBER_SUBKEY_EXTENSION, c);
426           if ((ef[i].szIdent[0] >= 0x20) && (ef[i].szIdent[0] < 0x80))
427             {
428               memcpy (szIdent, ef[i].szIdent, ef[i].dwIdentLength);
429               pt = szIdent + ef[i].dwIdentLength;
430             }
431           else
432             {
433               BinaryToHexString (ef[i].szIdent, ef[i].dwIdentLength, szIdent,
434                                  sizeof (szIdent));
435               pt = szIdent + ef[i].dwIdentLength * 4;
436             }
437           *pt = '\0';
438           if (ef[i].dwOffset == 0)
439             {
440               sprintf (szBuf, "%s=%s", ef[i].szExt, szIdent);
441             }
442           else
443             {
444               sprintf (szBuf, "%s=%s,%ld", ef[i].szExt, szIdent,
445                        ef[i].dwOffset);
446             }
447           ret =
448             RegSetValueEx (hKey, szSubKey, 0, REG_SZ, szBuf,
449                            strlen (szBuf) + 1);
450           if (ret != ERROR_SUCCESS)
451             {
452               fRet = FALSE;
453               break;
454             }
455           c++;
456         }                       /* if ( ef[i].szExt[0] != 0 ){ */
457     }                           /* for ( i=0; i<iEfs; i++ ){ */
458   if (fRet)
459     for (i = c; i < iExtNum; i++)
460       {
461         sprintf (szSubKey, "%s%d", FIBER_SUBKEY_EXTENSION, i);
462         RegDeleteValue (hKey, szSubKey);
463       }
464
465   RegCloseKey (hKey);
466
467   return (fRet);
468 }
469
470
471 BOOL
472 InitializeRegistry (VOID)
473 {
474   DWORD ret;
475   HKEY hKey;
476   BOOL fRet = TRUE;
477   DWORD dwDisposition;
478   int i;
479   char szBuf[64];
480
481   ret = RegCreateKeyEx (HKEY_LOCAL_MACHINE,
482                         FIBER_SUBKEY,
483                         0,
484                         "",
485                         0, KEY_READ | KEY_WRITE, NULL, &hKey, &dwDisposition);
486   if (ret != ERROR_SUCCESS)
487     {
488       printf ("Error: cannot create registry.\n");
489       return (FALSE);
490     }
491
492   szBuf[0] = FIBER_EXTNUM;
493   ret = RegSetValueEx (hKey, FIBER_SUBKEY_EXTNUM, 0, REG_BINARY, szBuf, 1);
494   if (ret != ERROR_SUCCESS)
495     {
496       fRet = FALSE;
497       goto Exit;
498     }
499
500   ret = RegSetValueEx (hKey, FIBER_SUBKEY_EXECUTEUNKNOWNEXT, 0,
501                        REG_BINARY, "\x1", 1);
502   if (ret != ERROR_SUCCESS)
503     {
504       fRet = FALSE;
505       goto Exit;
506     }
507   ret = RegSetValueEx (hKey, FIBER_SUBKEY_EXECUTEURL, 0,
508                        REG_BINARY, "\x1", 1);
509   if (ret != ERROR_SUCCESS)
510     {
511       fRet = FALSE;
512       goto Exit;
513     }
514   ret = RegSetValueEx (hKey, FIBER_SUBKEY_TRUSTEXT, 0, REG_BINARY, "\x1", 1);
515   if (ret != ERROR_SUCCESS)
516     {
517       fRet = FALSE;
518       goto Exit;
519     }
520   ret = RegSetValueEx (hKey, FIBER_SUBKEY_OVERRIDEEXT, 0,
521                        REG_BINARY, "\x1", 1);
522   if (ret != ERROR_SUCCESS)
523     {
524       fRet = FALSE;
525       goto Exit;
526     }
527   RegCloseKey (hKey);
528
529   /* init ef */
530   iExtNum = FIBER_EXTNUM;
531   ef = efInit;
532   i = 0;
533   while (ef[i].dwIdentLength != 0)
534     i++;
535   iEfs = ++i;
536
537   /* write ef */
538   WriteRegistry ();
539
540 Exit:
541   return (fRet);
542 }
543
544
545 BOOL
546 ReadRegistry (VOID)
547 {
548   DWORD ret;
549   HKEY hKey;
550   char szBuf[256];
551   DWORD dwBufLen;
552   char szSubKey[256];
553   BOOL fRet = TRUE;
554   int i;
555
556   ret = RegOpenKeyEx (HKEY_LOCAL_MACHINE,
557                       FIBER_SUBKEY, 0, KEY_EXECUTE, &</