Advertisement
Guest User

clipboard.c

a guest
Dec 2nd, 2011
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 16.65 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <io.h>
  4. #include <fcntl.h>
  5. #include <windows.h>
  6.  
  7. #ifndef CF_DIBV5
  8. #define CF_DIBV5 17
  9. #endif
  10.  
  11. #define MAXDATA 1000
  12.  
  13. static int maxdata = MAXDATA;
  14. static int interpret_newlines = 1;
  15.  
  16. typedef enum {
  17.   FORMAT_DEFAULT,
  18.   FORMAT_STRING,
  19.   FORMAT_WSTRING,
  20.   FORMAT_HEX,
  21.   FORMAT_BINARY
  22. } output_format_type;
  23.  
  24. const char *
  25. clipboard_format_name (UINT format)
  26. {
  27.   static char bfr[100];
  28.  
  29.   if (GetClipboardFormatName (format, bfr, sizeof (bfr)))
  30.     return bfr;
  31.  
  32.   if (format >= CF_GDIOBJFIRST && format <= CF_GDIOBJLAST)
  33.     {
  34.       sprintf (bfr, "CF_GDIOBJFIRST+%d", format - CF_GDIOBJFIRST);
  35.       return bfr;
  36.     }
  37.  
  38.   if (format >= CF_PRIVATEFIRST && format <= CF_PRIVATELAST)
  39.     {
  40.       sprintf (bfr, "CF_PRIVATEFIRST+%d", format - CF_PRIVATEFIRST);
  41.       return bfr;
  42.     }
  43.  
  44.   switch (format)
  45.     {
  46. #define CASE(x) case CF_##x: return "CF_" # x
  47.       CASE (BITMAP);
  48.       CASE (DIB);
  49.       CASE (DIBV5);
  50.       CASE (DIF);
  51.       CASE (DSPBITMAP);
  52.       CASE (DSPENHMETAFILE);
  53.       CASE (DSPMETAFILEPICT);
  54.       CASE (DSPTEXT);
  55.       CASE (ENHMETAFILE);
  56.       CASE (HDROP);
  57.       CASE (LOCALE);
  58.       CASE (METAFILEPICT);
  59.       CASE (OEMTEXT);
  60.       CASE (OWNERDISPLAY);
  61.       CASE (PALETTE);
  62.       CASE (PENDATA);
  63.       CASE (RIFF);
  64.       CASE (SYLK);
  65.       CASE (TEXT);
  66.       CASE (WAVE);
  67.       CASE (TIFF);
  68.       CASE (UNICODETEXT);
  69. #undef CASE
  70.     default:
  71.       sprintf (bfr, "UNKNOWN");
  72.       return bfr;
  73.     }
  74. }
  75.  
  76. static UINT
  77. parse_clipboard_format_name (const char *string)
  78. {
  79.   UINT format;
  80.  
  81.   if ((format = atoi (string)) > 0)
  82.     return format;
  83.  
  84. #define CASE(x) if (strcmp (string, "CF_" # x) == 0) return CF_##x
  85.   CASE (BITMAP);
  86.   CASE (DIB);
  87.   CASE (DIBV5);
  88.   CASE (DIF);
  89.   CASE (DSPBITMAP);
  90.   CASE (DSPENHMETAFILE);
  91.   CASE (DSPMETAFILEPICT);
  92.   CASE (DSPTEXT);
  93.   CASE (ENHMETAFILE);
  94.   CASE (HDROP);
  95.   CASE (LOCALE);
  96.   CASE (METAFILEPICT);
  97.   CASE (OEMTEXT);
  98.   CASE (OWNERDISPLAY);
  99.   CASE (PALETTE);
  100.   CASE (PENDATA);
  101.   CASE (RIFF);
  102.   CASE (SYLK);
  103.   CASE (TEXT);
  104.   CASE (WAVE);
  105.   CASE (TIFF);
  106.   CASE (UNICODETEXT);
  107. #undef CASE
  108.  
  109.   while ((format = EnumClipboardFormats (format)))
  110.     if (strcmp (string, clipboard_format_name (format)) == 0)
  111.       return format;
  112.  
  113.   return 0;
  114. }
  115.  
  116. static void
  117. print_string_data (const unsigned char *data,
  118.                    size_t               size)
  119. {
  120.   int i;
  121.  
  122.   for (i = 0; i < size; i++, data++)
  123.     {
  124.       if (i >= maxdata)
  125.         break;
  126.  
  127.       switch (*data)
  128.         {
  129.         case '\a':
  130.           printf ("\\a");
  131.           break;
  132.         case '\b':
  133.           printf ("\\b");
  134.           break;
  135.         case '\f':
  136.           printf ("\\f");
  137.           break;
  138.         case '\n':
  139.           printf ("\\n");
  140.           break;
  141.         case '\r':
  142.           if (interpret_newlines && data[1] == '\n')
  143.             {
  144.               printf ("\n");
  145.               data++;
  146.             }
  147.           else
  148.             printf ("\\r");
  149.           break;
  150.         case '\t':
  151.           printf ("\\t");
  152.           break;
  153.         case '\\':
  154.           printf ("\\\\");
  155.           break;
  156.         default:
  157.           if (*data >= ' ' && *data < 0177)
  158.             printf ("%c", *data);
  159.           else
  160.             printf ("\\%03o", (int) *data);
  161.         }
  162.     }
  163. }
  164.  
  165. static void
  166. print_unicode_data (const wchar_t *data,
  167.                     size_t         size)
  168. {
  169.   int i;
  170.  
  171.   for (i = 0; i < size; i++, data++)
  172.     {
  173.       if (i >= maxdata)
  174.         break;
  175.  
  176.       switch (*data)
  177.         {
  178.         case '\a':
  179.           printf ("\\a");
  180.           break;
  181.         case '\b':
  182.           printf ("\\b");
  183.           break;
  184.         case '\f':
  185.           printf ("\\f");
  186.           break;
  187.         case '\n':
  188.           printf ("\\n");
  189.           break;
  190.         case '\r':
  191.           if (interpret_newlines && data[1] == '\n')
  192.             {
  193.               printf ("\n");
  194.               data++;
  195.             }
  196.           else
  197.             printf ("\\r");
  198.           break;
  199.         case '\t':
  200.           printf ("\\t");
  201.           break;
  202.         case '\\':
  203.           printf ("\\\\");
  204.           break;
  205.         default:
  206.           if (*data >= ' ' && *data < 0177)
  207.             printf ("%c", *data);
  208.           else
  209.             printf ("\\u%04x", *data);
  210.         }
  211.     }
  212. }
  213.  
  214.  
  215. static void
  216. print_hex_data (const unsigned int *data,
  217.                 size_t              size)
  218. {
  219.   int i;
  220.  
  221.   for (i = 0; i < size; i++, data++)
  222.     {
  223.       if (i >= maxdata)
  224.         break;
  225.  
  226.       printf ("%08x", *data);
  227.       if ((i % 8) == 7)
  228.         printf ("\n");
  229.       else
  230.         printf (" ");
  231.     }  
  232. }
  233.  
  234. static int
  235. format_for_specific_handle (UINT format)
  236. {
  237.   switch (format)
  238.     {
  239.     case CF_BITMAP:
  240.     case CF_ENHMETAFILE:
  241.     case CF_HDROP:
  242.       return 1;
  243.     }
  244.   return 0;
  245. }
  246.  
  247. static char *
  248. compression_type (DWORD compression)
  249. {
  250.   static char buf[20];
  251.  
  252.   switch (compression)
  253.     {
  254. #define CASE(x) case BI_##x: return "BI_"#x
  255.       CASE (RGB);
  256.       CASE (RLE8);
  257.       CASE (RLE4);
  258.       CASE (BITFIELDS);
  259.       CASE (JPEG);
  260.       CASE (PNG);
  261. #undef CASE
  262.     default:
  263.       sprintf (buf, "%#lx", compression);
  264.       return buf;
  265.     }
  266. }
  267.  
  268. static int
  269. print_colors (const BITMAPINFOHEADER *bi,
  270.               const RGBQUAD          *rgb)
  271. {
  272.   if (bi->biCompression == BI_BITFIELDS &&
  273.       bi->biSize == sizeof (BITMAPINFOHEADER))
  274.     {
  275.       const DWORD *mask = (DWORD *) rgb;
  276.      
  277.       printf ("{%08lx,%08lx,%08lx}", mask[0], mask[1], mask[2]);
  278.  
  279.       return 3*4;
  280.     }
  281.  
  282.   if (bi->biBitCount == 1)
  283.     {
  284.       int i;
  285.  
  286.       printf ("rgb[2]{");
  287.       for (i = 0; i < 2; i++)
  288.         {
  289.           printf ("%02x%02x%02x}",
  290.                   rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue);
  291.           if (i == 0)
  292.             printf (",");
  293.         }
  294.       printf ("}");
  295.  
  296.       return 2*4;
  297.     }
  298.  
  299.   if (bi->biBitCount == 4 || bi->biBitCount == 8)
  300.     {
  301.       int ncolors = 16;
  302.       int i;
  303.  
  304.       if (bi->biClrUsed > 0)
  305.         ncolors = bi->biClrUsed;
  306.      
  307.       printf ("rgb[%d]{", ncolors);
  308.       for (i = 0; i < ncolors; i++)
  309.         {
  310.           printf ("%02x%02x%02x}",
  311.                   rgb[i].rgbRed, rgb[i].rgbGreen, rgb[i].rgbBlue);
  312.           if (i < ncolors-1)
  313.             printf (",");
  314.         }
  315.       printf ("}");
  316.  
  317.       return ncolors * 4;
  318.     }
  319.  
  320.   printf ("{}");
  321.   return 0;
  322. }
  323.  
  324. static void
  325. print_dib (const void *data,
  326.            SIZE_T      size)
  327. {
  328.   const BITMAPINFO *bmi = (BITMAPINFO *) data;
  329.   int color_table_size;
  330.   int image_size;
  331.  
  332.   printf ("bmi{\n"
  333.           " Header=\n"
  334.           " bi{\n"
  335.           "  Size=%ld, Width=%ld, Height=%ld, Planes=%d, BitCount=%d,\n"
  336.           "  Compression=%s, SizeImage=%ld, XPelsPerMeter=%ld, YPelsPerMeter=%ld,\n"
  337.           "  ClrUsed=%ld, ClrImportant=%ld\n"
  338.           " },Colors=",
  339.           bmi->bmiHeader.biSize, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, bmi->bmiHeader.biPlanes, bmi->bmiHeader.biBitCount,
  340.           compression_type (bmi->bmiHeader.biCompression),
  341.           bmi->bmiHeader.biSizeImage, bmi->bmiHeader.biXPelsPerMeter, bmi->bmiHeader.biYPelsPerMeter,
  342.           bmi->bmiHeader.biClrUsed, bmi->bmiHeader.biClrImportant);
  343.  
  344.   color_table_size = print_colors (&bmi->bmiHeader, bmi->bmiColors);
  345.   image_size = ((((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth) / 8) + 3 ) &  ~3) * bmi->bmiHeader.biHeight;
  346.   printf ("\n"
  347.           "},\n");
  348.   print_hex_data ((const unsigned int *)((char *) data +
  349.                                          bmi->bmiHeader.biSize +
  350.                                          color_table_size),
  351.                   image_size/4);
  352. }
  353.  
  354. static void
  355. print_dibv5 (const void *data,
  356.              SIZE_T      size)
  357. {
  358.   const BITMAPV5HEADER *bV5 = (BITMAPV5HEADER *) data;
  359.   int color_table_size;
  360.   int image_size;
  361.  
  362.   printf ("bV5{\n"
  363.           " Size=%ld, Width=%ld, Height=%ld, Planes=%d, BitCount=%d,\n"
  364.           " Compression=%s, SizeImage=%ld, XPelsPerMeter=%ld, YPelsPerMeter=%ld,\n"
  365.           " ClrUsed=%ld, ClrImportant=%ld,\n"
  366.           " RedMask=%08lx, GreenMask=%08lx, BlueMask=%08lx, AlphaMask=%08lx,\n"
  367.           " CsType=%ld (%c%c%c%c)\n"
  368.           "},\n",
  369.           bV5->bV5Size, bV5->bV5Width, bV5->bV5Height, bV5->bV5Planes, bV5->bV5BitCount,
  370.           compression_type (bV5->bV5Compression),
  371.           bV5->bV5SizeImage, bV5->bV5XPelsPerMeter, bV5->bV5YPelsPerMeter,
  372.           bV5->bV5ClrUsed, bV5->bV5ClrImportant,
  373.           bV5->bV5RedMask, bV5->bV5GreenMask, bV5->bV5BlueMask, bV5->bV5AlphaMask,
  374.           bV5->bV5CSType,
  375.           ((char *)&bV5->bV5CSType)[3], ((char *)&bV5->bV5CSType)[2],
  376.           ((char *)&bV5->bV5CSType)[1], ((char *)&bV5->bV5CSType)[0]);
  377.   printf ("colortable");
  378.   color_table_size = print_colors ((BITMAPINFOHEADER *) bV5,
  379.                                    (RGBQUAD*) ((char *)bV5) + bV5->bV5Size);
  380.   image_size = ((((bV5->bV5BitCount * bV5->bV5Width) / 8) + 3 ) &  ~3) * bV5->bV5Height;
  381.   printf ("\n");
  382.   print_hex_data ((const unsigned int *)((char *) data +
  383.                                          bV5->bV5Size +
  384.                                          color_table_size),
  385.                   image_size/4);
  386. }
  387.  
  388. static void
  389. print_data (output_format_type   output_format,
  390.             UINT                 format,
  391.             const unsigned char *data,
  392.             SIZE_T               size)
  393. {
  394.   switch (output_format)
  395.     {
  396.     case FORMAT_DEFAULT:
  397.       switch (format)
  398.         {
  399.         case CF_DIB:
  400.           print_dib (data, size);
  401.           break;
  402.         case CF_DIBV5:
  403.           print_dibv5 (data, size);
  404.           break;
  405.         default:
  406.           goto _FORMAT_STRING;
  407.         }
  408.       break;
  409.     case FORMAT_STRING: _FORMAT_STRING:
  410.       print_string_data (data, size);
  411.       break;
  412.     case FORMAT_WSTRING:
  413.       print_unicode_data ((wchar_t *) data, (size+1)/2);
  414.       break;
  415.     case FORMAT_HEX:
  416.       print_hex_data ((unsigned int *) data, (size+3)/4);
  417.       break;
  418.     case FORMAT_BINARY:
  419.       _setmode (fileno (stdout), O_BINARY);
  420.       fwrite (data, size, 1, stdout);
  421.       return;
  422.     }
  423.   printf ("\n");
  424. }
  425.  
  426. static void
  427. print_format_for_specific_handle (UINT   format,
  428.                                   HANDLE handle)
  429. {
  430.   switch (format)
  431.     {
  432.     case CF_BITMAP:
  433.       {
  434.         HANDLE handle = GetClipboardData (format);
  435.         BITMAP bm;
  436.  
  437.         if (!GetObject (handle, sizeof (BITMAP), (void *) &bm))
  438.           fprintf (stderr, "GetObject failed.\n"), exit (1);
  439.  
  440.         printf ("bm{\n"
  441.                 " Type=%ld, Width=%ld, Height=%ld, WidthBytes=%ld,\n"
  442.                 " Planes=%d, BitsPixel=%d,\n"
  443.                 " bmBits=",
  444.                 bm.bmType, bm.bmWidth, bm.bmHeight, bm.bmWidthBytes,
  445.                 bm.bmPlanes, bm.bmBitsPixel);
  446.         if (bm.bmBits != NULL)
  447.           print_data (FORMAT_HEX, CF_BITMAP, bm.bmBits, bm.bmHeight*bm.bmWidthBytes);
  448.         else
  449.           printf ("0");
  450.         printf ("\n"
  451.                 "}");
  452.       }
  453.       break;
  454.     default:
  455.       printf ("%p", handle);
  456.     }
  457. }
  458.  
  459. static void
  460. usage (const char *progname)
  461. {
  462.   fprintf (stderr, "Usage: %s [-m maxdata] [-b|-h|-n|-u|-i filename|-o filename]... (-l|-g format|-p format)\n", progname);
  463. }
  464.  
  465. int
  466. main (int    argc,
  467.       char **argv)
  468. {
  469.   UINT format = 0;
  470.   HANDLE handle;
  471.   int i;
  472.   output_format_type output_format = FORMAT_DEFAULT;
  473.  
  474.   if (argc < 2)
  475.     usage (argv[0]), exit (1);
  476.  
  477.   if (!OpenClipboard (NULL))
  478.     fprintf (stderr, "OpenClipboard failed.\n"), exit (1);
  479.  
  480.   /* Traverse options twice, first set flags */
  481.   for (i = 1; i < argc; i++)
  482.     {
  483.       if (strcmp (argv[i], "-i") == 0)
  484.         {
  485.           if (i + 1 == argc)
  486.             usage (argv[0]), exit (1);
  487.  
  488.           i++;
  489.           if (freopen (argv[i], "r", stdin) == NULL)
  490.             fprintf (stderr, "Could not open %s for reading.\n", argv[i]), exit (1);
  491.         }
  492.       else if (strcmp (argv[i], "-o") == 0)
  493.         {
  494.           if (i + 1 == argc)
  495.             usage (argv[0]), exit (1);
  496.  
  497.           i++;
  498.           if (freopen (argv[i], "w", stdout) == NULL)
  499.             fprintf (stderr, "Could not open %s for writing.\n", argv[i]), exit (1);
  500.         }
  501.       else if (strcmp (argv[i], "-n") == 0)
  502.         {
  503.           interpret_newlines = 0;
  504.         }
  505.       else if (strcmp (argv[i], "-u") == 0)
  506.         {
  507.           output_format = FORMAT_WSTRING;
  508.         }
  509.       else if (strcmp (argv[i], "-h") == 0)
  510.         {
  511.           output_format = FORMAT_HEX;
  512.         }
  513.       else if (strcmp (argv[i], "-b") == 0)
  514.         {
  515.           output_format = FORMAT_BINARY;
  516.         }
  517.       else if (strcmp (argv[i], "-g") == 0)
  518.         {
  519.           if (i + 1 == argc)
  520.             usage (argv[0]), exit (1);
  521.  
  522.           i++;
  523.         }
  524.       else if (strcmp (argv[i], "-m") == 0)
  525.         {
  526.           if (argc < 3 || (maxdata = atoi (argv[i+1])) <= 0)
  527.             usage (argv[0]), exit (1);
  528.         }
  529.       else if (strcmp (argv[i], "-p") == 0)
  530.         {
  531.           if (i + 1 == argc)
  532.             usage (argv[0]), exit (1);
  533.         }
  534.     }
  535.  
  536.   /* Then interpret what to do */
  537.   for (i = 1; i < argc; i++)
  538.     {
  539.       if (strcmp (argv[i], "-e") == 0)
  540.         {
  541.           if (!EmptyClipboard ())
  542.             fprintf (stderr, "EmptyClipboard() failed.\n"), exit (1);
  543.         }
  544.       else if (strcmp (argv[i], "-l") == 0)
  545.         {
  546.           HWND owner = GetClipboardOwner ();
  547.           DWORD owner_id = 0;
  548.  
  549.           if (owner == NULL)
  550.             printf ("no owner\n");
  551.           else if (GetWindowThreadProcessId (owner, &owner_id) != 0 && owner_id != 0)
  552.             printf ("owner: %p (pid: %ld)\n", owner, owner_id);
  553.           else
  554.             printf ("owner: %p\n", owner);
  555.          
  556.           while ((format = EnumClipboardFormats (format)))
  557.             printf ("%d: %s\n", format, clipboard_format_name (format));
  558.         }
  559.       else if (strcmp (argv[i], "-g") == 0)
  560.         {
  561.           if ((format = parse_clipboard_format_name (argv[i+1])) == 0)
  562.             fprintf (stderr, "Unrecognized clipboard format %s.\n", argv[i+1]), exit (1);
  563.  
  564.           if ((handle = GetClipboardData (format)) == NULL)
  565.             fprintf (stderr, "GetClipboardData(%d) failed.\n", format), exit (1);
  566.  
  567.           if (format_for_specific_handle (format))
  568.             {
  569.               print_format_for_specific_handle (format, handle);
  570.             }
  571.           else
  572.             {
  573.               SIZE_T size;
  574.               unsigned char *data;
  575.  
  576.               if ((size = GlobalSize (handle)) == 0)
  577.                 fprintf (stderr, "GlobalSize(%p) failed.\n", handle), exit (1);
  578.              
  579.               if ((data = GlobalLock (handle)) == NULL)
  580.                 fprintf (stderr, "GlobalLock(%p) failed.\n", handle), exit (1);
  581.               print_data (output_format, format, data, size);
  582.               GlobalUnlock (handle);
  583.             }
  584.  
  585.           i++;
  586.         }
  587.       else if (strcmp (argv[i], "-p") == 0)
  588.         {
  589.           int buffer_size = 1000;
  590.           int in_use = 0;
  591.           int nread;
  592.           char *buffer;
  593.  
  594.           if ((format = parse_clipboard_format_name (argv[i+1])) == 0)
  595.             {
  596.               if ((format = RegisterClipboardFormat (argv[i+1])) == 0)
  597.                 fprintf (stderr, "RegisterClipboardFormat(%s) failed.\n", argv[i+1]), exit (1);
  598.             }
  599.  
  600.           if ((handle = GlobalAlloc (GMEM_MOVEABLE, buffer_size)) == NULL)
  601.             fprintf (stderr, "GlobalAlloc(%d) failed.\n", buffer_size), exit (1);
  602.          
  603.           buffer = GlobalLock (handle);
  604.  
  605.           if (output_format == FORMAT_BINARY)
  606.             _setmode (fileno (stdin), O_BINARY);
  607.  
  608.           while ((nread = fread (buffer + in_use, 1, buffer_size - in_use, stdin)) > 0)
  609.             {
  610.               if (nread < buffer_size - in_use && ferror (stdin))
  611.                 fprintf (stderr, "Error reading after %d bytes.\n", in_use + nread), exit (1);
  612.               in_use += nread;
  613.               if (in_use == buffer_size)
  614.                 {
  615.                   buffer_size *= 1.5;
  616.                   GlobalUnlock (handle);
  617.                   if ((handle = GlobalReAlloc (handle, buffer_size, GMEM_MOVEABLE)) == NULL)
  618.                     fprintf (stderr, "GlobalReAlloc(%d) failed.\n", buffer_size), exit (1);
  619.                   buffer = GlobalLock (handle);
  620.                 }
  621.             }
  622.  
  623.           GlobalUnlock (handle);
  624.           if ((handle = GlobalReAlloc (handle, in_use, GMEM_MOVEABLE)) == NULL)
  625.             fprintf (stderr, "GlobalReAlloc(%d) failed.\n", in_use), exit (1);
  626.  
  627.           if (SetClipboardData (format, handle) == NULL)
  628.             fprintf (stderr, "GetClipboardData(%d) failed.\n", format), exit (1);
  629.  
  630.           GlobalUnlock (handle);
  631.  
  632.         }
  633.     }
  634.  
  635.   CloseClipboard ();
  636.  
  637.   return 0;
  638. }
  639.  
  640.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement