Hosting Flash no carga los recursos de swf (xml, imagen, etc.)

Intenté conseguir al principio un lector swf con gtk2 en mi máquina Unix. Trabajado, pude renderizar archivos swf simples. Ahora, estoy tratando de agregar una configuración a mi archivo flash con una configuración xml, agregar una imagen, etc. Fallo, no obtendré el pase geturlnotify (). Aquí está mi código:

<code>#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>

#include <gtk/gtk.h> 
#include <gdk/gdkx.h>
#include "npupp.h"

#define FLASH_PLUGIN_SO "./libflashplayer.so"

void *flash_plugin_handle;

NPNetscapeFuncs browserFuncs;
NPPluginFuncs   pluginFuncs;

GtkWidget *main_window;

char* fileName = NULL;
NPStream *       stream;
const char * uagent = "Axt/1.0";

//Default window size
int WINDOW_XSIZE = 800;
int WINDOW_YSIZE = 600;

//Default child window position (flash player)
int xPosition = 0;
int yPosition = 0;

NPError (*iNP_Initialize)(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs);
NPError (*iNP_Shutdown)();
char*   (*iNP_GetMIMEDescription)();

void* loadFlashPluginSo() {
  void *handle;

  handle = dlopen(FLASH_PLUGIN_SO, RTLD_LAZY | RTLD_LOCAL);
  if(!handle) {
    fprintf(stderr, "[-] error loading libflashplayer.so: %s\n", dlerror());
    exit(1);
  } 
  fprintf(stderr,"[+] loaded libflashplayer.so\n");
  return handle;
}

void* loadSymbol(void *handle, const char *name) {
  char *error;
  void *ret;

  ret = dlsym(handle, name);

  if((error = dlerror()) != NULL) {
    fprintf(stderr, "[-] error loading symbol %s: %s\n", name, error);
    exit(1);
  } else {
    fprintf(stderr,"[+] loaded symbol %s, address: %p\n", name, ret);
  }
  return ret;
}

void loadNPEntryPoints(void *handle) {
  iNP_Initialize=loadSymbol(handle, "NP_Initialize");
  iNP_Shutdown=loadSymbol(handle, "NP_Shutdown");
  iNP_GetMIMEDescription = loadSymbol(handle,"NP_GetMIMEDescription");
}

void printPluginEntrypoints(NPPluginFuncs* pFuncs) {
  fprintf(stderr,"[*] NPP struct:\n");
  fprintf(stderr,"\t- NPP_size:                 %8d\n",pFuncs->size);
  fprintf(stderr,"\t- NPP_version:              %8d\n",pFuncs->version);
  fprintf(stderr,"\t- NPP_NewProcPtr:           %p\n", pFuncs->newp);
  fprintf(stderr,"\t- NPP_DestroyProcPtr:       %p\n", pFuncs->destroy);
  fprintf(stderr,"\t- NPP_SetWindowProcPtr:     %p\n", pFuncs->setwindow);
  fprintf(stderr,"\t- NPP_NewStreamProcPtr:     %p\n", pFuncs->newstream);
  fprintf(stderr,"\t- NPP_DestroyStreamProcPtr: %p\n", pFuncs->destroystream);
  fprintf(stderr,"\t- NPP_StreamAsFileProcPtr:  %p\n", pFuncs->asfile);
  fprintf(stderr,"\t- NPP_WriteReadyProcPtr:    %p\n", pFuncs->writeready);
  fprintf(stderr,"\t- NPP_WriteProcPtr:         %p\n", pFuncs->write);
  fprintf(stderr,"\t- NPP_PrintProcPtr:         %p\n", pFuncs->print);
  fprintf(stderr,"\t- NPP_HandleEventProcPtr:   %p\n", pFuncs->event);
  fprintf(stderr,"\t- NPP_URLNotifyProcPtr:     %p\n", pFuncs->urlnotify);
  fprintf(stderr,"\t- javaClass:                %p\n", pFuncs->javaClass);
  fprintf(stderr,"\t- NPP_GetValueProcPtr:      %p\n", pFuncs->getvalue);
  fprintf(stderr,"\t- NPP_SetValueProcPtr:      %p\n", pFuncs->setvalue);
}

NPError NPN_GetValueProc(NPP instance, NPNVariable variable, void *ret_value) {
    fprintf(stderr,"[D] NPN_GetValueProc instance:%p, variable:%d, abi_mask:%d\n", instance, variable, 0);

    switch (variable) {
    case NPNVSupportsXEmbedBool:
      *((int*)ret_value)= PR_TRUE;
      break;
    //Unix and solaris fix
    case NPNVToolkit:
      *((int*)ret_value)= NPNVGtk2;
      break;
    case NPNVnetscapeWindow:
      *((int*)ret_value)= PR_TRUE;
      break;
    default:
      *((int*)ret_value)=PR_FALSE;
      break;
    }
    return NPERR_NO_ERROR;
}

const char* NPN_UserAgentProc(NPP instance) {
    fprintf(stderr,"[D] NPN_UserAgentProc instance:%p\n", instance);
    return uagent;
}

NPError NPN_GetURLProc(NPP instance, const char* url, const char* window) {
    fprintf(stderr,"[D] NPN_GetURLProcPtr:%p, url: %s, window: %s\n", instance, url, window);
    return NPERR_NO_ERROR;
}

NPIdentifier NPN_GetStringIdentifierProc(const NPUTF8* name) {
    return (NPIdentifier)0x41424344; //Unique
}

static 
gboolean plug_removed_cb (GtkWidget *widget, gpointer data) {
    fprintf(stderr,"[!] plug_removed_cb\n");
    return TRUE;
}

static void
socket_unrealize_cb(GtkWidget *widget, gpointer data) {
    fprintf(stderr, "[!] socket_unrealize_cb\n");
}


static NPWindow *
npwindow_construct (GtkWidget *widget) {
  NPWindow *npwindow;
  NPSetWindowCallbackStruct *ws_info = NULL;

  GdkWindow *parent_win = widget->window;

  GtkWidget *socketWidget = gtk_socket_new();

  gtk_widget_set_parent_window(socketWidget, parent_win);
  gtk_widget_set_uposition(socketWidget, xPosition, yPosition);

  g_signal_connect(socketWidget, "plug_removed", G_CALLBACK(plug_removed_cb), NULL);
  g_signal_connect(socketWidget, "unrealize", G_CALLBACK(socket_unrealize_cb), NULL);
  g_signal_connect(socketWidget, "destroy", G_CALLBACK(gtk_widget_destroyed), &socketWidget);


  gpointer user_data = NULL;
  gdk_window_get_user_data(parent_win, &user_data);

  GtkContainer *container = GTK_CONTAINER(user_data);
  gtk_container_add(container, socketWidget);
  gtk_widget_realize(socketWidget);

  GtkAllocation new_allocation;
  new_allocation.x = 0;
  new_allocation.y = 0;
  new_allocation.width = WINDOW_XSIZE;
  new_allocation.height = WINDOW_YSIZE;
  gtk_widget_size_allocate(socketWidget, &new_allocation);

  gtk_widget_show(socketWidget);
  gdk_flush();

  GdkNativeWindow ww = gtk_socket_get_id(GTK_SOCKET(socketWidget));
  GdkWindow *w = gdk_window_lookup(ww); 

  npwindow = malloc (sizeof (NPWindow));
  npwindow->window = (void*)(unsigned long)ww;
  npwindow->x = 0;
  npwindow->y = 0;
  npwindow->width  = WINDOW_XSIZE;
  npwindow->height = WINDOW_YSIZE;

  ws_info = malloc(sizeof (NPSetWindowCallbackStruct));
  ws_info->type = NP_SETWINDOW;
  ws_info->display = GDK_WINDOW_XDISPLAY(w);
  ws_info->colormap = GDK_COLORMAP_XCOLORMAP(gdk_drawable_get_colormap(w));
  GdkVisual* gdkVisual = gdk_drawable_get_visual(w);
  ws_info->visual = GDK_VISUAL_XVISUAL(gdkVisual);
  ws_info->depth = gdkVisual->depth;

  npwindow->ws_info = ws_info;
  npwindow->type = NPWindowTypeWindow;

  return npwindow;
}

static NPStream *
npstream_construct() {
    NPStream *stream = malloc(sizeof(NPStream));
    stream->url=fileName;
    stream->notifyData = 0x00000000;

    fprintf(stderr,"[D] NPN_StreamConstructed: %p\n", stream);

    return stream;
}

bool NPN_GetPropertyProc(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result) {
    fprintf(stderr,"[D] NPN_GetPropertyProc: %p\n", result);
    result->type = NPVariantType_Object;
    result->value.objectValue= (NPObject*)1;
    return TRUE;
}


bool NPN_InvokeProc(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) {
    fprintf(stderr,"[D] NPN_InvokeProc: %p\n", result);
    result->type= NPVariantType_String;
    result->value.stringValue.utf8characters=fileName;
    result->value.stringValue.utf8length=strlen(fileName);
    return TRUE;
}

void NPN_ReleaseVariantValueProc(NPVariant *variant) {
}

void NPN_ReleaseObjectProc(NPObject *obj) {
}

NPObject*  NPN_CreateObjectProc(NPP npp, NPClass *aClass) {
    return (NPObject*)1;
}

NPObject*  NPN_RetainObjectProc(NPObject *obj) {
    return (NPObject*)1;
}

NPError NPN_GetURLNotifyProc(NPP instance, const char* url, const char* window, void* notifyData) {
    fprintf(stderr,"[D] NPN_GetURLNotifyProc:%p, url: %s, window: %s\n", instance, url, window);
    return 0;
}

NPN_GetURL, NPN_GetURLNotify, and NPP_URLNotify

void initNPNetscapeFuncs(NPNetscapeFuncs *bFuncs) {
  int i=0;

  for(i=1; i<sizeof(*bFuncs)/sizeof(ssize_t); i++)
    *(((ssize_t*)bFuncs)+i)=i+1000;

  bFuncs->geturl=NPN_GetURLProc;
  bFuncs->getvalue=NPN_GetValueProc;
  bFuncs->uagent=NPN_UserAgentProc;
  bFuncs->getproperty=NPN_GetPropertyProc;
  bFuncs->getstringidentifier=NPN_GetStringIdentifierProc;
  bFuncs->invoke=NPN_InvokeProc;
  bFuncs->releasevariantvalue=NPN_ReleaseVariantValueProc;
  bFuncs->releaseobject=NPN_ReleaseObjectProc;
  bFuncs->createobject=NPN_CreateObjectProc;
  bFuncs->retainobject=NPN_RetainObjectProc;
  bFuncs->geturlnotify=NPN_GetURLNotifyProc;
  bFuncs->size= sizeof(bFuncs);
  bFuncs->version= (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;;
}

static void destroy(GtkWidget *widget, gpointer data) {
    gtk_main_quit ();
}

static void checkError(const char* str, NPError err) {
  if(err == NPERR_NO_ERROR)
    fprintf(stderr, "[+] %s: success\n", str);
  else
    fprintf(stderr, "[-] %s: failed (%d)\n", str, err);
    fflush(NULL);
}

int main(int argc, char **argv) 
{
  int c;
  extern char *optarg;

  while ((c = getopt(argc, argv, "f:w:h:x:y:")) != EOF){
    switch (c) {
      case 'f':
        fileName = optarg;
        fprintf (stderr, "[+] Filename: %s\n", optarg);
        break;
      case 'w':
        WINDOW_XSIZE = atoi(optarg);
        fprintf (stderr, "[+] WINDOW_XSIZE: %s\n", optarg);
        break;
      case 'h':
        WINDOW_YSIZE = atoi(optarg);
        fprintf (stderr, "[+] WINDOW_YSIZE: %s\n", optarg);
        break;
      case 'x':
        xPosition = atoi(optarg);
        fprintf (stderr, "[+] Position in x: %s\n", optarg);
        break;
      case 'y':
        yPosition = atoi(optarg);
        fprintf (stderr, "[+] Position in y: %s\n", optarg);
        break;
      case '?':
        if (optopt == 'f' | optopt == 'w' | optopt == 'h')
          fprintf (stderr, "[-] Option -%c requires an argument.\n", optopt);
        else if (isprint (optopt))
          fprintf (stderr, "[-] Unknown option `-%c'.\n", optopt);
        else
          fprintf (stderr,"[-] Unknown option character `\\x%x'.\n", optopt);
          exit(-1);
      default:
        fprintf(stderr,"[-] Usage: %s -f <swffile> -x <xsize> -y <ysize>\n", argv[0]);
        exit(-1);
    }
  }

  gtk_init (&argc, &argv);
  main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_usize (main_window, WINDOW_XSIZE, WINDOW_YSIZE);
  gtk_widget_set_uposition (main_window, xPosition, yPosition);
  g_signal_connect (G_OBJECT (main_window), "destroy", G_CALLBACK (destroy), NULL);
  gtk_widget_realize(main_window);
  gtk_widget_show_all(main_window);
  fprintf(stderr,"[+] created GTK widget\n");

  flash_plugin_handle = loadFlashPluginSo();

  loadNPEntryPoints(flash_plugin_handle);
  fprintf(stderr,"[+] initialized flash plugin entry points\n");

  initNPNetscapeFuncs(&browserFuncs);
  fprintf(stderr,"[+] initialized browser functions\n");

  checkError("NP_Initialize", iNP_Initialize(&browserFuncs, &pluginFuncs));

  printPluginEntrypoints(&pluginFuncs);

  NPWindow *npwin = npwindow_construct(main_window);
  fprintf(stderr,"[+] created NPWindow widget\n");

  NPP_t *instancep = malloc(sizeof(NPP_t));
  memset(instancep,0,sizeof(sizeof(NPP_t)));
  NPP instance     = instancep;

  NPSavedData* saved = malloc(sizeof(NPSavedData));
  memset(saved,0,sizeof(sizeof(NPSavedData)));

  stream = npstream_construct();
  uint16_t stype;

  char *xargv[]= {"quality", "bgcolor", "width", "height", "allowScriptAccess", "loop" };
  char *xargm[]= {"high", "#000000", "1360", "768", "always", "false" };


  checkError("NPN_New", pluginFuncs.newp("application/x-shockwave-flash", instance, NP_EMBED, 0, xargv, xargm, saved));
  checkError("NPN_SetWindow", pluginFuncs.setwindow(instance, npwin));
  checkError("NPN_NewStream", pluginFuncs.newstream(instance, "application/x-shockwave-flash", stream, 0,  &stype));


  FILE *pp;

  char buffer[8192];
  pp = fopen(fileName,"rb");

  int len;

  while((len=fread(buffer, 1, sizeof(buffer), pp)) != 0) {
    pluginFuncs.writeready(instance, stream);
    pluginFuncs.write(instance, stream, 0, len, buffer);
  }

  fclose(pp);

  checkError("NPN_DestroyStream",pluginFuncs.destroystream(instance, stream, NPRES_DONE));

  free(stream);

  gtk_main ();

  checkError("NPN_Destroy",pluginFuncs.destroy(instance, &saved));


  checkError("NP_Shutdown", iNP_Shutdown());

  dlclose(flash_plugin_handle);
  return 0;
}
</code>

Si carga un swf sin xml. Funciona. Cuando tuve una configuración para mi xml. Para.

Aquí está la salida que obtengo:

<code>~/test-flash$ ./test-flash -f xml_sample.swf -w 400 -h 600 -x 15 -y 15
[+] Filename: xml_sample.swf
[+] WINDOW_XSIZE: 400
[+] WINDOW_YSIZE: 600
[+] Position in x: 15
[+] Position in y: 15
[+] created GTK widget
[+] loaded libflashplayer.so
[+] loaded symbol NP_Initialize, address: 0x7ff03fb634d0
[+] loaded symbol NP_Shutdown, address: 0x7ff03fb634c0
[+] loaded symbol NP_GetMIMEDescription, address: 0x7ff03fb63870
[+] initialized flash plugin entry points
[+] initialized browser functions
[+] NP_Initialize: success
[*] NPP struct:
        - NPP_size:                        0
        - NPP_version:                     0
        - NPP_NewProcPtr:           0x7ff03fb63990
        - NPP_DestroyProcPtr:       0x7ff03fb63980
        - NPP_SetWindowProcPtr:     0x7ff03fb63970
        - NPP_NewStreamProcPtr:     0x7ff03fb63960
        - NPP_DestroyStreamProcPtr: 0x7ff03fb63910
        - NPP_StreamAsFileProcPtr:  0x7ff03fb63920
        - NPP_WriteReadyProcPtr:    0x7ff03fb63950
        - NPP_WriteProcPtr:         0x7ff03fb63940
        - NPP_PrintProcPtr:         0x7ff03fb63900
        - NPP_HandleEventProcPtr:   0x7ff03fb638f0
        - NPP_URLNotifyProcPtr:     0x7ff03fb63930
        - javaClass:                (nil)
        - NPP_GetValueProcPtr:      0x7ff03fb63860
        - NPP_SetValueProcPtr:      (nil)
[+] created NPWindow widget
[D] NPN_StreamConstructed: 0x25ce5e0
[D] NPN_GetValueProc instance:0x25cc720, variable:14, abi_mask:0
[D] NPN_GetValueProc instance:0x25cc720, variable:268435469, abi_mask:0
[D] NPN_UserAgentProc instance:(nil)
[D] NPN_GetValueProc instance:0x25cc720, variable:15, abi_mask:0
[D] NPN_GetValueProc instance:0x25cc720, variable:15, abi_mask:0
[D] NPN_GetValueProc instance:0x25cc720, variable:18, abi_mask:0
[+] NPN_New: success
[D] NPN_GetValueProc instance:0x25cc720, variable:14, abi_mask:0
[+] NPN_SetWindow: success
[D] NPN_GetURLNotifyProc:0x25cc720, url: javascript:top.location+"__flashplugin_unique__", window: (null)
[D] NPN_GetValueProc instance:0x25cc720, variable:15, abi_mask:0
[+] NPN_NewStream: success
Lenght: 455
[D] NPN_UserAgentProc instance:0x25cc720
[+] NPN_DestroyStream: success
[D] NPN_GetURLNotifyProc:0x25cc720, url: sample.xml, window: (null)
</code>

¡Gracias!

EDITAR:

Intenté algo como esto (el código está en la función NPN_GetURLNotifyProc). pero luego, mi aplicación se congela dentro de mi geturlnotifyproc ...

<code>NPStream s;
uint16 stype;
memset(&s,0,sizeof(NPStream));
s.url = strdup(url);
fprintf(stderr, "URL: %s\n", s.url);
checkError("NPN_NewStream", pluginFuncs.newstream(instance,"text/html",&s,0,&stype));    
    writeStream(instance, &pluginFuncs, &s);
pluginFuncs.urlnotify(instance,url,NPRES_DONE,notifyData);
checkError("NPN_DestroyStream", pluginFuncs.destroystream(instance,&s,NPRES_DONE));
            free((void*)s.url);
</code>

Respuestas a la pregunta(1)

Su respuesta a la pregunta