随笔 - 74, 文章 - 0, 评论 - 26, 引用 - 0
数据加载中……

在Windows Mobile 5中使用DirectShow控制摄像头-转

By Amit Ranjan
July 21, 2006

A number of Windows Mobile 5.0 APIs (for example, SHCameraCapture) make it trivial for a mobile application developer to access a camera, but their ease of use comes at a price—flexibility. Most of the time, using the API directly would offer a solution, but sometimes you need more control and flexibility. That's where Microsoft's DirectShow framework comes in. This article shows how to use DirectShow to access a camera. It demonstrates how to build a filter graph manually and how to handle graph events in the application message handler. Having some prior knowledge of DirectShow and COM will be helpful, but it's not necessary.

Figure 1 depicts the components in the filter graph you will use to capture video.

Figure 1: Filter Graph for Video Capture

The camera is the hardware component. For an application to interact with the camera, it would need to talk to its drivers. Next, the video capture filter enables an application to capture video. After capture, you encode the data using WMV9EncMediaObject, a DirectX Media Object (DMO). You can use a DMO inside a filter graph with the help of a DMO Wrapper filter. Next, the encoded video data needs to be multiplexed. You use a Windows Media ASF writer filter for this task. The ASF writer multiplexes the video data and writes it to an .asf file. With that, your filter graph is ready. Now, it's just a matter of running it. As you will see, building the graph is pretty easy too.

Set the Build Environment

First, you need to set the build environment. Add the following libraries in the linker setting of a Visual Studio 2005 Smart Device project:

  • dmoguids.lib
  • strmiids.lib
  • strmbase.lib
  • uuid.lib

Also include the following header files in your project:

  • atlbase.h
  • dmodshow.h
  • dmoreg.h
  • wmcodecids.h

 

Note: For the sake of clarity, this example doesn't show error handling. However, a real world application would require error handling.

Building the Graph

A filter graph that performs audio or video capture is known as a Capture graph. DirectShow provides a Capture Graph Builder object that exposes an interface called ICaptureGraphBuilder2; it exposes methods to help build and control a capture graph.

First, create instances of IGraphBuilder and ICaptureGraphBuilder2 by using the COM function CoCreateInstance:

HRESULT hResult = S_OK;

IGraphBuilder *pFilterGraph;

ICaptureGraphBuilder2 *pCaptureGraphBuilder;

hResult=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,

                         IID_IGraphBuilder,(void**)&pFilterGraph);

hResult=CoCreateInstance(CLSID_CaptureGraphBuilder, NULL,

                         CLSCTX_INPROC, IID_ICaptureGraphBuilder2,

                         (void**)& pCaptureGraphBuilder);

CoCreateInstance takes five parameters:

  1. The first is a class ID.
  2. The second decides whether the object created is part of an aggregator.
  3. The third specifies the context in which the newly created object would run.
  4. The fourth parameter is a reference to the identifier of the interface you will use to communicate with the object.
  5. The last parameter is the address of the variable that receives the interface pointer requested.

Once you have created the IGraphBuilder and ICaptureGraphBulder2 instances, you need to call the SetFilterGraph method of the ICaptureGraphBuilder2 interface:

hResult = m_pCaptureGraphBuilder->SetFiltergraph( pFilterGraph );

The SetFilterGraph method takes a pointer to the IGraphBuilder interface. This specifies which filter graph the capture graph builder will use. If you don't call the SetFilterGraph method, the Capture graph builder automatically creates a graph when it needs it.

Now, you're ready to create an instance of the video capture filter. The following code initializes a Video capture filter, the pointer of which is returned by the CoCreateInstance:

IBaseFilter *pVideoCaptureFilter;

hResult=CoCreateInstance(CLSID_VideoCapture, NULL, CLSCTX_INPROC,

                         IID_IBaseFilter, (void**)&pVideoCaptureFilter);

You then need to get a pointer to IPersistPropertyBag from the video capture filter. You use this pointer to set the capture device (in other words, the camera) that the capture filter will use, as follows:

IPersistPropertyBag *pPropertyBag;

hResult=pVideoCaptureFilter->QueryInterface( &pPropertyBag );

Now, you need to get a handle on the camera you will use to capture video. You can enumerate the available camera devices by using the FindFirstDevice and FindNextDevice functions. You can have multiple cameras present on a device. (HTC Universal is one example.) To keep the code simple for this example, use FindFirstDevice to get the first available camera on the device as follows:

DEVMGR_DEVICE_INFORMATION devInfo;

CComVariant  CamName;

CPropertyBag PropBag;

GUID guidCamera = { 0xCB998A05, 0x122C, 0x4166, 0x84, 0x6A, 0x93,

                    0x3E, 0x4D, 0x7E, 0x3C, 0x86 };

devInfo.dwSize = sizeof(devInfo);

FindFirstDevice( DeviceSearchByGuid, &guidCamera, & devInfo);

CamName=devInfo.szLegacyName

PropBag.Write( _T("VCapName"), &CamName );

pPropertyBag->Load( &PropBag, NULL );

hResult =pFilterGraph->AddFilter( pVideoCaptureFilter,

                                  _T("Video Capture Filter") );

pPropertyBag.Release();

Note the first parameter in the FindFirstDevice, DeviceSearchByGuid. It specifies the search type. Other options are DeviceSearchByLegacyName, DeviceSearchByDeviceName, and so forth. DeviceSearchByGuid is the most reliable way to find a capture device. The information regarding the device is returned in the DEVMGR_DEVICE_INFORMATION structure. You store the szLegacyName value in the CComVariant variable, and you need an object that has implemented IPropertyBag interface.

In the code sample, CPropertyBag is a custom class that has implemented IPropertyBag. This object is needed to pass the capture device name to the filter. The string VCapName identifies the filter property for the name of the video capture device. Once you have set the capture device, you can add the Video capture filter to the filter graph. You use the AddFilter method of the graph manager for this. This method takes two parameters: the first is the pointer to the filter that is to be added, and the second is the name of the filter. The second parameter can be NULL; in this case, the filter graph manager generates a unique name for the filter. If you have provided a name that conflicts with some other filter, the manager will modify the name to make it unique.

You then need to instantiate the WMV9 encoder:

IBaseFilter *pVideoEncoder;

IDMOWrapperFilter *pWrapperFilter;

hResult=CoCreateInstance(CLSID_DMOWrapperFilter, NULL,CLSCTX_INPROC,

                         IID_IBaseFilter, (void**)&pVideoEncoder);

hResult =pVideoEncoder->QueryInterface( &pWrapperFilter );

hResult =pWrapperFilter->Init( CLSID_CWMV9EncMediaObject,

                               DMOCATEGORY_VIDEO_ENCODER );

hResult=pFilterGraph->AddFilter( pVideoEncoder, L"WMV9DMO Encoder");

Because the WMV9 encoder is a DMO, you can't add/use it like other filters. But DirectShow provides a wrapper filter that enables you to use a DMO like any other filter. You first create an instance of the DMO wrapper filter and then initialize the WMV9 encoder DMO with it. After initializing the DMO, you add it into the filter graph as follows:

IBaseFilter *pASFMultiplexer;

IFileSinkFilter *pFileSinkFilter;

hResult = pCaptureGraphBuilder->SetOutputFileName(&MEDIASUBTYPE_Asf, T("\\test.asf"), &pASFMultiplexer, &pFileSinkFilter );

You have added the source and the transform filter in the filter graph, so the last thing remaining is adding a sink filter in the graph. For this, you call the SetOutputFileName method of ICaptureGraphBuilder2. The first parameter is a media subtype; the second parameter is the name of the file in which you want to save the video; the third parameter is the address of a pointer that receives the multiplexer's interface; and the fourth parameter receives the file writers' interface.

With that, your filter graph is ready. All you need to do is connect the source filter, encoder, and multiplexer. You can achieve this by using the RenderStream method of the graph builder, as follows:

hResult = pCaptureGraphBuilder->RenderStream( &PIN_CATEGORY_CAPTURE,

                                         &MEDIATYPE_Video,

                                         m_pVideoCaptureFilter,

                                         pVideoEncoder,

                                         pASFMultiplexer );

 

The first parameter is the pin category, which can be NULL to match any category.The second parameter specifies the media type. The third, fourth, and fifth parameters specify a starting filter, an intermediate filter, and a sink filter, respectively. The method connects the source filter to the transform filter and then the transform filter to the sink filter.

Now your graph is ready, and you can start capturing the video.

Controlling the Graph

Before capturing video, you need two more things: the ImediaEventEx and IMediaControl pointers. IMediaEventEx derives from IMediaEvent, which supports event notification from the filter graph and individual filters to the application.ImediaEventEx provides a method to the register window that receives a message when any event occurs.

IMediaControl is an interface exposed by the filter graph that allows an application to control the streaming media through the graph. The application can use this to start, stop, or pause the running graph.The following code sample first queries the filter graph for its IMediaEventEx interface. Once it gets the pointer to the IMediaEventEx interface, it then calls its method SetNotifyWindow, passing it the handle to the window that handles the message. The second parameter is the message that will be passed as notification to the Windows message handler. The third parameter is the instance data (this can be 0):

IMediaEventEx *pMediaEvent;

IMediaControl *pMediaControl;

#define WM_GRAPHNOTIFY WM_APP+1

hResult =pFilterGraph->QueryInterface( IID_IMediaEventEx, (void**)&pMediaEvent );

hResult =pMediaEvent->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHNOTIFY,0);

hResult=pFilterGraph->QueryInterface(&pMediaControl);

hResult =pMediaControl->Run();

When an event occurs, DirectShow will send WM_GRAPHNOTIFY to the specified windows.

Note: WM_GRAPHNOTIFY is used here as an example. This can be any application-defined message.

Next, you get the pointer to the IMediaControl interface. You'll use this interface to control the graph. Call its Run method to put the entire graph into a running state. The following code shows how to start and stop capture by throwing the

ControlStream method of CaptureGraphBuilder:

LONGLONG dwStart  = 0, dwEnd = 0;

WORD wStartCookie = 1, wEndCookie = 2;

dwEnd=MAXLONGLONG;

 

//start capturing

hResult=pCaptureGraphBuilder->ControlStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video,pVideoCaptureFilter, &dwStart, &dwEnd,wStartCookie, wEndCookie);

 

//Stop capturing

dwStart=0;

hResult=pFilterGraph->QueryInterface(&pMediaSeeking );

hResult=pMediaSeeking->GetCurrentPosition( &dwEnd );

hResult= pCaptureGraphBuilder->ControlStream(

   &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVideoCaptureFilter,

   &dwStart, &dwEnd, wStartCookie, wEndCookie );

The code uses the search criteria supplied in the method call to locate an output pin on the capture filter. ControlStream enables an application to control streams without it needing to enumerate filters and pins in the graph.Start and End specify the start and stop times (MAX_LONGLONG is the largest possible reference time value). When you start, the End is set to MAXLONLONG. When you want to stop, you first get the current position of the stream by using the GetCurrentPosition method of the IMediaSeeking interface. You then call the ControlStream method with Start set at 0 and End set at the current position.You now have the graph ready and running. You can start using it to capture and save in an .asf file.

Handling the Graph Events

Because an application will control the graph, you need to write the code to facilitate that. You already have registered the window and message with the filter graph, so the only thing remaining is to handle the message in the window's message handler as follows:

BOOL CALLBACK VidCapDlgProc(HWND hDlg,UINT Msg,WPARAM wParam, LPARAM lParam)

{

   ... ... ... ...

   case WM_GRAPHNOTIFY:

      {

         ProcessGraphMessage();

      }

   ... ... ... ...

}

ProcessGraphMessage()

{

   HRESULT hResult=S_OK;

   long leventCode, param1, param2;

   while(hResult=pEvent->GetEvent(&leventCode, &param1, &param2, 0),

   SUCCEEDED(hResult))

   {

      hResult = pEvent->FreeEventParams(leventCode, param1, param2);

      if (EC_STREAM_CONTROL_STOPPED == leventCode)

      {

         pMediaControl->Stop();

         break;

      }

      else if(EC_CAP_FILE_COMPLETED== leventCode)

      {

         //Handle the file capture completed event

      }

      else if(EC_CAP_FILE_WRITE_ERROR== leventCode)

      {

         //Handle the file write error event

      }

   }

}

You handle the WM_GRAPHNOTIFY message in the windows handler. DirectShow sends this message to the application when any event arises. The application calls a user-defined method to process the events. The GetEvent method of the IMediaEvent interface retrieves the event code and two event parameters from the queue.Because the message loop and event notification are asynchronous, the queue might hold more then one event. Hence, the GetEvent code is called in a loop until it returns a failure code. Also, whenever you call GetEvent, it's important to call FreeEvent to free the resource associated with the event parameter. And, being the good programmer that you are, you won't forget to release the resources afterwards, will you? Call Release on every object that you have created, as follows:

PVideoCaptureFilter->Release ();

pVideoEncoder->Release ();

pMediaEvent ->Release();

pMediaSeeking ->Release();

pASFMultiplexer->Release();

pFileSinkFilter->Release();

pWrapperFilter ->Release();

pFilterGraph->Release();

pCaptureGraphBuilder->Release();

 

What Have You Learned?

You now understand how to create, run, and control a filter graph manually. By using the DirectShow framework to capture from a camera, you gain good control with ease.

posted @ 2008-11-28 14:06 井泉 阅读(7369) | 评论 (10)编辑 收藏

如何在运行时确定对象类型(RTTI) 转

RTTI 是“Runtime Type Information”的缩写,意思是:运行时类型信息。它提供了运行时确定对象类型的方法。本文将简略介绍 RTTI 的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI;本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和 dynamic_cast。
    其实,RTTI 在C++中并不是什么新的东西,它早在十多年以前就已经出现了。但是大多数开发人员,包括许多高层次的C++程序员对它并不怎么熟悉,更不用说使用 RTTI 来设计和编写应用程序了。
    一些面向对象专家在传播自己的设计理念时,大多都主张在设计和开发中明智地使用虚拟成员函数,而不用 RTTI 机制。但是,在很多情况下,虚拟函数无法克服本身的局限。每每涉及到处理异类容器和根基类层次(如 MFC)时,不可避免要对对象类型进行动态判断,也就是动态类型的侦测。如何确定对象的动态类型呢?答案是使用内建的 RTTI 中的运算符:typeid 和 dynamic_cast。
    首先让我们来设计一个类层次,假设我们创建了某个处理文件的抽象基类。它声明下列纯虚拟函数:open()、close()、read()和 write():
class File
{
public:
virtual int open(const string & filename)=0;
virtual int close(const string & filename)=0;
//
virtual ~File()=0; // 记住添加纯虚拟析构函数(dtor)
};
现在从 File 类派生的类要实现基类的纯虚拟函数,同时还要提供一些其他的操作。假设派生类为 DiskFile,除了实现基类的纯虚拟函数外,还要实现自己的flush()和defragment()操作:
class DiskFile: public File
{
public:
int open(const string & filename);

// 实现其他的纯虚拟函数
......

// 自己的专有操作
virtual int flush();
virtual int defragment();
};
接着,又从 DiskFile 类派生两个类,假设为 TextFile 和 MediaFile。前者针对文本文件,后者针对音频和视频文件:
class TextFile: public DiskFile
{
// ......
int sort_by_words();
};

class MediaFile: public DiskFile
{
//......
};
我们之所以要创建这样的类层次,是因为这样做以后可以创建多态对象,如:
File *pfile; // *pfile的静态类型是 File
if(some_condition)
pfile = new TextFile; // 动态类型是 TextFile
else
pfile = new DiskFile; // 动态类型是 DiskFile
    假设你正在开发一个基于图形用户界面(GUI)的文件管理器,每个文件都可以以图标方式显示。当鼠标移到图标上并单击右键时,文件管理器打开一个菜单,每 个文件除了共同的菜单项,不同的文件类型还有不同的菜单项。如:共同的菜单项有“打开”“拷贝”、和“粘贴”,此外,还有一些针对特殊文件的专门操作。比 如,文本文件会有“编辑”操作,而多媒体文件则会有“播放”菜单。为了使用 RTTI 来动态定制菜单,文件管理器必须侦测每个文件的动态类型。利用 运算符 typeid 可以获取与某个对象关联的运行时类型信息。typeid 有一个参数,传递对象或类型名。因此,为了确定 x 的动态类型是不是Y,可以用表达式:typeid(x) == typeid(Y)实现:
#include <typeinfo> // typeid 需要的头文件
void menu::build(const File * pfile)
{
if (typeid(*pfile)==typeid(TextFile))
{
add_option("edit");
}
else if (typeid(*pfile)==typeid(MediaFile))
{
add_option("play");
}
}
    使用 typeid 要注意一个问题,那就是某些编译器(如 Visual C++)默认状态是禁用 RTTI 的,目的是消除性能上的开销。如果你的程序确实使用了 RTTI,一定要记住在编译前启用 RTTI。使用 typeid 可能产生一些将来的维护问题。假设你决定扩展上述的类层次,从MediaFile 派生另一个叫 LocalizeMedia 的类,用这个类表示带有不同语言说明文字的媒体文件。但 LocalizeMedia 本质上还是个 MediaFile 类型的文件。因此,当用户在该类文件图标上单击右键时,文件管理器必须提供一个“播放”菜单。可惜 build()成员函数会调用失败,原因是你没有检查这种特定的文件类型。为了解决这个问题,你必须象下面这样对 build() 打补丁:
void menu::build(const File * pfile)
{

//......

else if (typeid(*pfile)==typeid(LocalizedMedia))
{
add_option("play");
}
}
    唉,这种做法真是显得太业余了,以后每次添加新的类,毫无疑问都必须打类似的补丁。显然,这不是一个理想的解决方案。这个时候我们就要用到 dynamic_cast,这个运算符用于多态编程中保证在运行时发生正确的转换(即编译器无法验证是否发生正确的转换)。用它来确定某个对象是 MediaFile 对象还是它的派生类对象。dynamic_cast 常用于从多态编程基类指针向派生类指针的向下类型转换。它有两个参数:一个是类型名;另一个是多态对象的指针或引用。其功能是在运行时将对象强制转换为目标类型并返回布尔型结果。也就是说,如果该函数成功地并且是动态的将 *pfile 强制转换为 MediaFile,那么 pfile的动态类型是 MediaFile 或者是它的派生类。否则,pfile 则为其它的类型:
void menu::build(const File * pfile)
{
if (dynamic_cast <MediaFile *> (pfile))
{
// pfile 是 MediaFile 或者是MediaFile的派生类 LocalizedMedia
add_option("play");
}
else if (dynamic_cast <TextFile*> (pfile))
{
// pfile 是 TextFile 是TextFile的派生类
add_option("edit");
}
}
    细细想一下,虽然使用 dynamic_cast 确实很好地解决了我们的问题,但也需要我们付出代价,那就是与 typeid 相比,dynamic_cast 不是一个常量时间的操作。为了确定是否能完成强制类型转换,dynamic_cast`必须在运行时进行一些转换细节操作。因此在使用 dynamic_cast 操作时,应该权衡对性能的影响。

posted @ 2008-11-19 14:59 井泉 阅读(947) | 评论 (1)编辑 收藏

Visual C++ 如何:在各种字符串类型之间进行转换 msdn

http://msdn.microsoft.com/zh-cn/library/ms235631(VS.80).aspx

posted @ 2008-11-19 13:59 井泉 阅读(130) | 评论 (0)编辑 收藏

wince6.0移植之oal 转

     摘要: [克隆BSP] Clone一个BSP. WinCE6.0安装armv4i架构后,里面提供了一个名字为DeviceEmulator的BSP. 这个BSP是s3c2410的BSP.我的是s3c2440a,就克隆这个吧.   [移植OAL] WinCE5.0的OAL是编译成为一个静态库oal.lib,然后与内核nk.lib静态编译成kernel.exe,也就是nk.exe. ...  阅读全文

posted @ 2008-11-12 10:19 井泉 阅读(1044) | 评论 (0)编辑 收藏

直接运行内存中的程序 转

     摘要: Windows的PE加载器在启动程序的时候,会将磁盘上的文件加载到内存,然后做很多操作,如函数导入表重定位,变量预处理之类的。这位仁兄等于是自己写了一个PE加载器。直接将内存中的程序启动。记得以前的“红色代码”病毒也有相同的特性。    直接启动内存中的程序相当于加了一个壳,可以把程序加密保存,运行时解密到内存,然后启动,不过对于增加破解难度还...  阅读全文

posted @ 2008-10-31 15:18 井泉 阅读(489) | 评论 (0)编辑 收藏

如何共享 DLL 中的所有数据 微软support

概要

Win 32 动态链接库 (DLL) 默认,这意味着使用 DLL 的每个应用程序获取它自己的 DLL 的数据的副本的情况下使用实例数据。 但是,就可以共享 DLL 数据之间所有使用该 DLL 的应用程序。

如果您需要共享仅部分 DLL 数据,Microsoft 建议创建一个新的节和而共享它。 如果您想共享的所有 DLL 静态数据,非常重要做两件事情:
第一次,DLL 必须使用 C 运行时的 DLL 版本 (例如 Crtdll.lib 或 Msvcrt.lib)。 请参阅您的产品文档更多有关使用 C 运行时 DLL 中。

注意: Crtdll.lib 不再 SDK,从 Windows NT 3.51 开始的一部分。 上次发布年 4 月 1995 年上的 MSDN 3.5 SDK。 Win 32 现在要求用户指定的由他们自己的编译器 vender 提供的 C 运行时 LIBs 他们自己的版本。
第二个,您需要指定.data 和.bss 共享。 通常,这样.def 文件的"SECTIONS"部分中。 例如:
   SECTIONS
.bss READ WRITE SHARED
.data READ WRITE SHARED
如果您要使用 Visual C++ 32-bit Edition,您必须指定此使用链接器上的部分开关。 例如:
link -section:.data,rws -section:.bss,rws
只有静态数据被共享。 用对作为 GlobalAlloc() 和 malloc() 这样的 API / 函数的调用动态分配的内存是仍然特定于调用进程。

系统试图加载每个进程中相同的地址处共享的内存块。 但是,如果块不能将加载到相同的内存地址,系统将共享的分区映射到一个不同的内存地址。 仍在共享内存。 请注意该共享节内部指针无效在这种情况下并不能放共享各节中。

更多信息

C 运行时使用全局变量。 如果 CRT 是静态与该 DLL,链接这些变量将在 DLL 的所有客户端之间共享并将最有可能导致的异常 c 0000005。

您要同时指定.data 和.bss 为共享,因为它们每个保存不同类型的数据。 .data 部分包含初始化的数据,.bss 部分保存未初始化的数据。

for sharing in DLL all data one reason is to have in between Win32 DLL (running on Windows NT) and Win32s consistent behavior (running on Windows 3.1). when running on Win32s,32-bit DLL shares among all of that use DLL processes its data。

请注意不需要共享所有数据 Win 32 和 Win32s 之间的行为完全相同。 DLL 可用于将变量存储为实例数据在 Win 32 线程本地存储 (TLS)。

for additional information,please see following article in Microsoft Knowledge Base:
109620 (http://support.microsoft.com/kb/109620/EN-US/) 在一个 Win 32 中创建实例数据 DLL

这篇文章中的信息适用于:
Microsoft Win32 Application Programming Interface 当用于
    Microsoft Windows NT 4.0
    Microsoft Windows NT 3.51 Service Pack 5
    Microsoft Windows NT 4.0
    Microsoft Windows 95
    Microsoft Windows 98 Standard Edition
    the operating system: Microsoft Windows 2000
    the operating system: Microsoft Windows XP

回到顶端

关键字: 
kbmt kbdll kbhowto kbipc kbkernbase KB109619 KbMtzh

posted @ 2008-10-28 15:07 井泉 阅读(706) | 评论 (0)编辑 收藏

.NET Compact Framework 2.0下调用EnumWindows(Callback方式) 转

发过一篇文章是.net cf 1.x实现EnumWindows,因为.net cf 1.x不支持Callback方式,所以实现起来比较繁琐,而且效率不高。.net cf 2.0中就不同了,已经加入了的对Callback的支持了,所以我们就可以调用EnumWindows这个API函数来遍历所有的窗口了,下面是我写的 一个Demo:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace EnumWindows
{
    public partial class Form1 : Form
    {
        public delegate int EnumWindowsProc(IntPtr hwnd, IntPtr lParam);

        EnumWindowsProc callbackDelegate;
        IntPtr callbackDelegatePointer;

        [DllImport("coredll.dll", SetLastError = true)]
        public static extern bool EnumWindows(IntPtr lpEnumFunc, uint lParam);
        [DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetWindowTextLength(IntPtr hWnd);
        [DllImport("coredll.dll")]
        public static extern int GetWindowText(IntPtr hWnd, [Out] StringBuilder lpString, int nMaxCount);
        public Form1()
        {
            InitializeComponent();

            callbackDelegate = new EnumWindowsProc(EnumWindowsCallbackProc);
            callbackDelegatePointer = Marshal.GetFunctionPointerForDelegate(callbackDelegate);

            EnumWindows(callbackDelegatePointer, 0);


        }

        public int EnumWindowsCallbackProc(IntPtr hwnd, IntPtr lParam)
        {
            int length = GetWindowTextLength(hwnd);
            StringBuilder sb = new StringBuilder(length + 1);
            GetWindowText(hwnd, sb, sb.Capacity);
            System.Diagnostics.Debug.WriteLine("Window: " + hwnd.ToString() + "," + sb.ToString());

            return 1;
        }
    }

}
vs.net 2005 下调试通过!

posted @ 2008-10-24 16:40 井泉 阅读(580) | 评论 (1)编辑 收藏

7个网络爱好者必装的Firefox插件 转

以下插件均适用于Firefox 3.0 。

1. Add N Edit Cookies 查看和修改本地的Cookie,Cookie欺骗必备。
下载:http://code.google.com/p/editcookie/downloads/list

2. User Agent Switcher 修改浏览器的User Agent,可以用来XSS。
下载:https://addons.mozilla.org/zh-CN/firefox/addon/59

3. RefControl  修改Referer引用,也可以用来XSS或者突破一些防盗链。关于Referer XSS的可以参考利用雅虎站长工具跨站给管理员挂马
下载:https://addons.mozilla.org/zh-CN/firefox/addon/953

4.Live HTTP Headers  记录本地的Get和Post数据,并可修改数据后重新提交。
下载:https://addons.mozilla.org/zh-CN/firefox/addon/3829

5.  Poster   用来Post和Get数据。
下载:https://addons.mozilla.org/fr/firefox/addon/2691

6. HackBar  小工具包,包含一些常用的工具。(SQL injection,XSS,加密等)
下载:http://devels-playground.blogspot.com/2008/07/new-hackbar-132.html

7. XSS-Me &SQL Inject-Me&Access-Me 分别用来检测XSS,SQL Inject和Access缺陷。
下载:http://securitycompass.com/exploitme.shtml

同时推荐下花儿开了用的Firefox插件。如果有更好的插件,请留言告诉我,谢谢。

posted @ 2008-10-23 15:27 井泉 阅读(488) | 评论 (1)编辑 收藏

三款工具助您将 Firefox 浏览器变为武器 转

不知屏幕前的你用的是什么浏览 器?由于目前针对Internet Explorer的恶意代码太多,笔者现在常用Firefox搜索东西。喜欢这种开源软件的理由很简单:安全并且拥有很多令人爱不释手的扩展插件,借助于 这些好东东我们可以放心地浏览网络、接收电子邮件。如今,为Firefox开发的扩展插件越来越多。下面就具体看看可以让我们将Firefox变为一个强 大武器的三大工具。不过,话又说回来,这些扩展程序并非专用于增强Firefox的安全性,但通过它使用起来却更加方便。

数据修改大师Tamper Data

如果你只能为自己的浏览安装一个安全卫士,则非“Tamper Data”莫属。过去,笔者用Paros Proxy 和 Burp Suite来阻止浏览器和Web服务器之间的请求信息和响应。现在这些任务可以借助于Firefox和Tamper Data实现,而无需对代理进行配置。易用就好嘛。

现在用浏览器上网冲浪离不开cookie,它是由 Web 页服务器置于你硬盘上的一个非常小的文本文件。或许可以这样讲它是你的身份证。虽然它只能由提供它的服务器来读取,不过它会泄露你的信息。如果你想访问的 网站需要一个唯一的cookie,或者说用户代理,那么笔者建议你在将cookie发送到Web服务器之前,先用Tamper Data截获其请求。然后,对其属性进行增加、修改等操作,然后再发送。我们甚至也可以在浏览器解释来自Web服务器的响应之前,对这种响应加以修改。我 们觉得安全的则留,不安全的则弃之。岂不妙哉!总之,这是一款对Web应用程序的安全感兴趣的众多网友的好工具。

下面给出Tamper Data的日志窗口:(图1)

图 1

Tamper Data的修改窗口:(图2)

图 2

安全高于一切:Paros和 Burp

1.Paros

正如其开发团队所言,Paros这个程序是为那些需要评估其Web应用程序的安全性而设计的。它用Java语言编写,并完全免费。通过Paros的代理特性,服务器和客户端的所有的HTTP和HTTPS数据,包括cookies和表单字段,都可以被截获和修改。

其功能当然是不错了。如捕捉功能,即可以手动捕捉和修改HTTP(和HTTPS)的 请求和响应;过滤器功能,即对HTTP消息模式进行检测并发出警告,帮助用户处理;扫描功能,即可以扫描一些常见的漏洞;日志功能,即允许用户查看并检查 所有的HTTP请求/响应内容。等等。如下图3

图 3

2.Burp套件

其实,Burp套件是一个用于攻击Web应用程序的集成性的平台。它包含很多工具, 如代理服务器、圈套程序、入侵程序、转发程序等,拥有许多接口,可以促进、加强攻击Web应用程序的进程。所有的插件共享Burp的健壮框架,可以处理 HTTP请求、认证、下游代理(downstream proxies)、日志、警告、可扩展性要求等。

Burp套件允许一个攻击者将手动的和自动的技术结合起来,列举、分析、攻击并查找web应用程序的漏洞。多种Burp工具有效地结合起来,可以共享信息,并且允许用一种工具找到的漏洞来形成用另外一种工具攻击的根据。

其关键特性有:

(1)能够被动地以一种非入侵方式“圈住”一个应用程序,并可使所有的请求都起源于用户的浏览器。

(2)一次单击就可以在插件之间传送数据请求。

(3)通过IburpExtender接口进行扩展,这也就容许了第三方的代码扩展Burp套件的功能。由一个插件处理的数据可以用任意的方式来影响另外一个插件的行为和结果。

(4)可以为下游代理、Web、代理认证和日志集中配置。

●Burp套件的下载地址为:http://portswigger.net/suite/

如果你对这些工具感兴趣,不妨下载试试。一定会为你带来惊喜的。

posted @ 2008-10-23 15:24 井泉 阅读(233) | 评论 (0)编辑 收藏

Building ARM assembly source from within VS 2005 转

Building ARM assembly source from within VS 2005

This is a little bit ugly, but it does the job. An unfortunate side effect of this build rule is that you end up deploying the .obj produced, because it becomes a project output, but I did this in twenty minutes while investigating another bug. Paste this into a file, name it "armasm.rules". Right click on the project, click "Custom Build Rules", from this dialog, choose "Find Existing..." Enjoy!

<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile Name="Arm ASM"
Version="8.00">
   <Rules>
      <CustomBuildRule 
         Name="Arm asm" DisplayName="Arm asm"
         CommandLine="armasm -o &quot;$(IntDir)\$(InputName).obj&quot; [$Inputs] "
         Outputs="$(IntDir)\$(InputName).obj"
         FileExtensions="*.asm"
         ExecutionDescription="Executing tool..."
      
>
      
<Properties></Properties>
      </CustomBuildRule>
   
</Rules>
</VisualStudioToolFile>

posted @ 2008-09-22 14:29 井泉 阅读(506) | 评论 (0)编辑 收藏

仅列出标题
共8页: 1 2 3 4 5 6 7 8