分享
 
 
 

从内存播放Flash。

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

前提:

被要求Flash必须加密,不能在硬盘上留下文件。

起点:

Flash 播放器的属性Movie接受本地文件名 或者 HTTP URL。

首先当然是在网络上寻找解决方案了。找了半天,发现一个国内的,一个国外的。都在出售。

奇怪的是,他们不约而同的都是用了Delphi。

根据了解的人透露,它是利用了Flash一个未公开的属性MovieData, 该属性文档中没有记录,但是从名称可以看出应该是应该是接受数据片的。

其国内的那一版目前还不支持最新的flash播放器。这让人不能不有点担忧。 因此还是尽量照自己的思路来。

思路:

最开始考虑的就是建一个协议(类似于rtsp的样子)来代替http,并把请求转到本地守护进程。

后来又想到还不如直接建立一个简陋的http服务器,直接使用http url , 这样子肯定是可行的,于是就着手写http服务器了。

写了个简单的测试程序,监听了一些http包,发现即使建立个简陋的http服务器,也需要了解一下rfc2612的,考虑到flash不同版本可能识别的响应及其标签,响应头还是蛮复杂的。

看rfc2612的时候突然想到, 建立http服务器是虚拟一个url;如果能够虚拟一个本地文件名,是不是更简单些呢? 照着这个思路,找了个把小时,当然也走了不少的弯路。最终发现可以用管道来处理。

因为管道客户端也是用CreateFile, ReadFile来处理的, 与普通文件一样。这样子就可以用管道名称来代替文件名来欺骗一下flash乐^_^

被欺骗的Flash读文件的时候:CreateFile, ReadFile实际上是读的是管道,只是他自己不知道而已. 而我们可以向管道写入任何内容,这不就达到目的了么?

写了段代码验证了一下,确实可行。 而且还模拟了网络的流环境(每次读10字节,延迟3ms),发现效果不错,正如预料的一样。

下面贴出来的代码来资源是测试程序,比较零乱。如果你仔细看了上面的内容,并且对于提到的属于没什么不解的话,应该就不用看下面的代码了。 附上来仅仅是为了备忘。

代码是一个console程序, vs2003环境。

假设有个样例Flash为Blue.swf。

设定的管道名称为: \\.\pipe\egbpipe

验证时先运行本程序,并保证blue.swf存在。然后打开flash播放器,用她播放文件"\\.\pipe\egbpipe"。

代码开始:

-------------

// PipeService.cpp : 定义控制台应用程序的入口点。

//

#include "stdafx.h"

#define BUFSIZE 1024

#define PIPE_TIMEOUT 1000

int __main(void);

int MyErrExit(char*);

int _tmain(int argc, _TCHAR* argv[])

{

__main();

return 0;

}

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <windows.h>

VOID InstanceThread(LPVOID);

VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

VOID GetAnswerToRequest(HANDLE hFile);

int xx = 0;

/*

\.pipeegbpipe

*/

int __main(void)

{

BOOL fConnected;

DWORD dwThreadId;

HANDLE hPipe, hThread;

LPTSTR lpszPipename = "\\\\.\\pipe\\egbpipe";

// The main loop creates an instance of the named pipe and

// then waits for a client to connect to it. When the client

// connects, a thread is created to handle communications

// with that client, and the loop is repeated.

for (;;)

{

hPipe = CreateNamedPipe(

lpszPipename, // pipe name

PIPE_ACCESS_DUPLEX, // read/write access

PIPE_TYPE_MESSAGE | // message type pipe

PIPE_READMODE_MESSAGE | // message-read mode

PIPE_WAIT, // blocking mode

PIPE_UNLIMITED_INSTANCES, // max. instances

BUFSIZE, // output buffer size

BUFSIZE, // input buffer size

PIPE_TIMEOUT, // client time-out

NULL); // no security attribute

if (hPipe == INVALID_HANDLE_VALUE)

MyErrExit("CreatePipe");

// Wait for the client to connect; if it succeeds,

// the function returns a nonzero value. If the function returns

// zero, GetLastError returns ERROR_PIPE_CONNECTED.

fConnected = ConnectNamedPipe(hPipe, NULL) ?

TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

if (fConnected)

{

// Create a thread for this client.

hThread = CreateThread(

NULL, // no security attribute

0, // default stack size

(LPTHREAD_START_ROUTINE) InstanceThread,

(LPVOID) hPipe, // thread parameter

0, // not suspended

&dwThreadId); // returns thread ID

if (hThread == NULL)

MyErrExit("CreateThread");

else

CloseHandle(hThread);

}

else

// The client could not connect, so close the pipe.

CloseHandle(hPipe);

}

return 1;

}

VOID InstanceThread(LPVOID lpvParam)

{

CHAR chRequest[BUFSIZE];

CHAR chReply[BUFSIZE];

DWORD cbBytesRead, cbReplyBytes, cbWritten;

BOOL fSuccess;

HANDLE hPipe;

// The thread's parameter is a handle to a pipe instance.

hPipe = (HANDLE) lpvParam;

// while (1)

{

// Read client requests from the pipe.

/* fSuccess = ReadFile(

hPipe, // handle to pipe

chRequest, // buffer to receive data

BUFSIZE, // size of buffer

&cbBytesRead, // number of bytes read

NULL); // not overlapped I/O

if (! fSuccess || cbBytesRead == 0)

break;

*/

//GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);

GetAnswerToRequest(hPipe);

/*

// Write the reply to the pipe.

fSuccess = WriteFile(

hPipe, // handle to pipe

chReply, // buffer to write from

cbReplyBytes, // number of bytes to write

&cbWritten, // number of bytes written

NULL); // not overlapped I/O

// if (! fSuccess || cbReplyBytes != cbWritten) break;

*/ }

// Flush the pipe to allow the client to read the pipe's contents

// before disconnecting. Then disconnect the pipe, and close the

// handle to this pipe instance.

FlushFileBuffers(hPipe);

DisconnectNamedPipe(hPipe);

CloseHandle(hPipe);

}

int MyErrExit(char* szInfo)

{

return MessageBox(0, szInfo, "Whoo", MB_OK);

}

VOID GetAnswerToRequest(HANDLE hFile)

{

const int BuffLen = 10;

byte buff[BuffLen] = {0};

FILE* f = fopen("blue.swf", "rb");

int iLen = BuffLen;

while(iLen == BuffLen)

{

iLen = fread(buff, sizeof(byte), BuffLen, f);

Sleep(3);

DWORD uLen = 0;

WriteFile(hFile, buff, iLen, &uLen, NULL);

}

_fcloseall( );

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有