青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 74, 文章 - 0, 評論 - 26, 引用 - 0
數(shù)據(jù)加載中……

在Windows Mobile 5中使用DirectShow控制攝像頭-轉(zhuǎn)

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 井泉 閱讀(7948) | 評論 (10)編輯 收藏

如何在運行時確定對象類型(RTTI) 轉(zhuǎn)

RTTI 是“Runtime Type Information”的縮寫,意思是:運行時類型信息。它提供了運行時確定對象類型的方法。本文將簡略介紹 RTTI 的一些背景知識、描述 RTTI 的概念,并通過具體例子和代碼介紹什么時候使用以及如何使用 RTTI;本文還將詳細描述兩個重要的 RTTI 運算符的使用方法,它們是 typeid 和 dynamic_cast。
    其實,RTTI 在C++中并不是什么新的東西,它早在十多年以前就已經(jīng)出現(xiàn)了。但是大多數(shù)開發(fā)人員,包括許多高層次的C++程序員對它并不怎么熟悉,更不用說使用 RTTI 來設(shè)計和編寫應(yīng)用程序了。
    一些面向?qū)ο髮<以趥鞑プ约旱脑O(shè)計理念時,大多都主張在設(shè)計和開發(fā)中明智地使用虛擬成員函數(shù),而不用 RTTI 機制。但是,在很多情況下,虛擬函數(shù)無法克服本身的局限。每每涉及到處理異類容器和根基類層次(如 MFC)時,不可避免要對對象類型進行動態(tài)判斷,也就是動態(tài)類型的偵測。如何確定對象的動態(tài)類型呢?答案是使用內(nèi)建的 RTTI 中的運算符:typeid 和 dynamic_cast。
    首先讓我們來設(shè)計一個類層次,假設(shè)我們創(chuàng)建了某個處理文件的抽象基類。它聲明下列純虛擬函數(shù):open()、close()、read()和 write():
class File
{
public:
virtual int open(const string & filename)=0;
virtual int close(const string & filename)=0;
//
virtual ~File()=0; // 記住添加純虛擬析構(gòu)函數(shù)(dtor)
};
現(xiàn)在從 File 類派生的類要實現(xiàn)基類的純虛擬函數(shù),同時還要提供一些其他的操作。假設(shè)派生類為 DiskFile,除了實現(xiàn)基類的純虛擬函數(shù)外,還要實現(xiàn)自己的flush()和defragment()操作:
class DiskFile: public File
{
public:
int open(const string & filename);

// 實現(xiàn)其他的純虛擬函數(shù)
......

// 自己的專有操作
virtual int flush();
virtual int defragment();
};
接著,又從 DiskFile 類派生兩個類,假設(shè)為 TextFile 和 MediaFile。前者針對文本文件,后者針對音頻和視頻文件:
class TextFile: public DiskFile
{
// ......
int sort_by_words();
};

class MediaFile: public DiskFile
{
//......
};
我們之所以要創(chuàng)建這樣的類層次,是因為這樣做以后可以創(chuàng)建多態(tài)對象,如:
File *pfile; // *pfile的靜態(tài)類型是 File
if(some_condition)
pfile = new TextFile; // 動態(tài)類型是 TextFile
else
pfile = new DiskFile; // 動態(tài)類型是 DiskFile
    假設(shè)你正在開發(fā)一個基于圖形用戶界面(GUI)的文件管理器,每個文件都可以以圖標方式顯示。當(dāng)鼠標移到圖標上并單擊右鍵時,文件管理器打開一個菜單,每 個文件除了共同的菜單項,不同的文件類型還有不同的菜單項。如:共同的菜單項有“打開”“拷貝”、和“粘貼”,此外,還有一些針對特殊文件的專門操作。比 如,文本文件會有“編輯”操作,而多媒體文件則會有“播放”菜單。為了使用 RTTI 來動態(tài)定制菜單,文件管理器必須偵測每個文件的動態(tài)類型。利用 運算符 typeid 可以獲取與某個對象關(guān)聯(lián)的運行時類型信息。typeid 有一個參數(shù),傳遞對象或類型名。因此,為了確定 x 的動態(tài)類型是不是Y,可以用表達式:typeid(x) == typeid(Y)實現(xiàn):
#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++)默認狀態(tài)是禁用 RTTI 的,目的是消除性能上的開銷。如果你的程序確實使用了 RTTI,一定要記住在編譯前啟用 RTTI。使用 typeid 可能產(chǎn)生一些將來的維護問題。假設(shè)你決定擴展上述的類層次,從MediaFile 派生另一個叫 LocalizeMedia 的類,用這個類表示帶有不同語言說明文字的媒體文件。但 LocalizeMedia 本質(zhì)上還是個 MediaFile 類型的文件。因此,當(dāng)用戶在該類文件圖標上單擊右鍵時,文件管理器必須提供一個“播放”菜單。可惜 build()成員函數(shù)會調(diào)用失敗,原因是你沒有檢查這種特定的文件類型。為了解決這個問題,你必須象下面這樣對 build() 打補丁:
void menu::build(const File * pfile)
{

//......

else if (typeid(*pfile)==typeid(LocalizedMedia))
{
add_option("play");
}
}
    唉,這種做法真是顯得太業(yè)余了,以后每次添加新的類,毫無疑問都必須打類似的補丁。顯然,這不是一個理想的解決方案。這個時候我們就要用到 dynamic_cast,這個運算符用于多態(tài)編程中保證在運行時發(fā)生正確的轉(zhuǎn)換(即編譯器無法驗證是否發(fā)生正確的轉(zhuǎn)換)。用它來確定某個對象是 MediaFile 對象還是它的派生類對象。dynamic_cast 常用于從多態(tài)編程基類指針向派生類指針的向下類型轉(zhuǎn)換。它有兩個參數(shù):一個是類型名;另一個是多態(tài)對象的指針或引用。其功能是在運行時將對象強制轉(zhuǎn)換為目標類型并返回布爾型結(jié)果。也就是說,如果該函數(shù)成功地并且是動態(tài)的將 *pfile 強制轉(zhuǎn)換為 MediaFile,那么 pfile的動態(tài)類型是 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 不是一個常量時間的操作。為了確定是否能完成強制類型轉(zhuǎn)換,dynamic_cast`必須在運行時進行一些轉(zhuǎn)換細節(jié)操作。因此在使用 dynamic_cast 操作時,應(yīng)該權(quán)衡對性能的影響。

posted @ 2008-11-19 14:59 井泉 閱讀(988) | 評論 (1)編輯 收藏

Visual C++ 如何:在各種字符串類型之間進行轉(zhuǎn)換 msdn

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

posted @ 2008-11-19 13:59 井泉 閱讀(145) | 評論 (0)編輯 收藏

wince6.0移植之oal 轉(zhuǎn)

     摘要: [克隆BSP] Clone一個BSP. WinCE6.0安裝armv4i架構(gòu)后,里面提供了一個名字為DeviceEmulator的BSP. 這個BSP是s3c2410的BSP.我的是s3c2440a,就克隆這個吧.   [移植OAL] WinCE5.0的OAL是編譯成為一個靜態(tài)庫oal.lib,然后與內(nèi)核nk.lib靜態(tài)編譯成kernel.exe,也就是nk.exe. ...  閱讀全文

posted @ 2008-11-12 10:19 井泉 閱讀(1057) | 評論 (0)編輯 收藏

直接運行內(nèi)存中的程序 轉(zhuǎn)

     摘要: Windows的PE加載器在啟動程序的時候,會將磁盤上的文件加載到內(nèi)存,然后做很多操作,如函數(shù)導(dǎo)入表重定位,變量預(yù)處理之類的。這位仁兄等于是自己寫了一個PE加載器。直接將內(nèi)存中的程序啟動。記得以前的“紅色代碼”病毒也有相同的特性。    直接啟動內(nèi)存中的程序相當(dāng)于加了一個殼,可以把程序加密保存,運行時解密到內(nèi)存,然后啟動,不過對于增加破解難度還...  閱讀全文

posted @ 2008-10-31 15:18 井泉 閱讀(511) | 評論 (0)編輯 收藏

如何共享 DLL 中的所有數(shù)據(jù) 微軟support

概要

Win 32 動態(tài)鏈接庫 (DLL) 默認,這意味著使用 DLL 的每個應(yīng)用程序獲取它自己的 DLL 的數(shù)據(jù)的副本的情況下使用實例數(shù)據(jù)。 但是,就可以共享 DLL 數(shù)據(jù)之間所有使用該 DLL 的應(yīng)用程序。

如果您需要共享僅部分 DLL 數(shù)據(jù),Microsoft 建議創(chuàng)建一個新的節(jié)和而共享它。 如果您想共享的所有 DLL 靜態(tài)數(shù)據(jù),非常重要做兩件事情:
第一次,DLL 必須使用 C 運行時的 DLL 版本 (例如 Crtdll.lib 或 Msvcrt.lib)。 請參閱您的產(chǎn)品文檔更多有關(guān)使用 C 運行時 DLL 中。

注意: Crtdll.lib 不再 SDK,從 Windows NT 3.51 開始的一部分。 上次發(fā)布年 4 月 1995 年上的 MSDN 3.5 SDK。 Win 32 現(xiàn)在要求用戶指定的由他們自己的編譯器 vender 提供的 C 運行時 LIBs 他們自己的版本。
第二個,您需要指定.data 和.bss 共享。 通常,這樣.def 文件的"SECTIONS"部分中。 例如:
   SECTIONS
.bss READ WRITE SHARED
.data READ WRITE SHARED
如果您要使用 Visual C++ 32-bit Edition,您必須指定此使用鏈接器上的部分開關(guān)。 例如:
link -section:.data,rws -section:.bss,rws
只有靜態(tài)數(shù)據(jù)被共享。 用對作為 GlobalAlloc() 和 malloc() 這樣的 API / 函數(shù)的調(diào)用動態(tài)分配的內(nèi)存是仍然特定于調(diào)用進程。

系統(tǒng)試圖加載每個進程中相同的地址處共享的內(nèi)存塊。 但是,如果塊不能將加載到相同的內(nèi)存地址,系統(tǒng)將共享的分區(qū)映射到一個不同的內(nèi)存地址。 仍在共享內(nèi)存。 請注意該共享節(jié)內(nèi)部指針無效在這種情況下并不能放共享各節(jié)中。

更多信息

C 運行時使用全局變量。 如果 CRT 是靜態(tài)與該 DLL,鏈接這些變量將在 DLL 的所有客戶端之間共享并將最有可能導(dǎo)致的異常 c 0000005。

您要同時指定.data 和.bss 為共享,因為它們每個保存不同類型的數(shù)據(jù)。 .data 部分包含初始化的數(shù)據(jù),.bss 部分保存未初始化的數(shù)據(jù)。

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。

請注意不需要共享所有數(shù)據(jù) Win 32 和 Win32s 之間的行為完全相同。 DLL 可用于將變量存儲為實例數(shù)據(jù)在 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 中創(chuàng)建實例數(shù)據(jù) DLL

這篇文章中的信息適用于:
Microsoft Win32 Application Programming Interface 當(dāng)用于
    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

回到頂端

關(guān)鍵字: 
kbmt kbdll kbhowto kbipc kbkernbase KB109619 KbMtzh

posted @ 2008-10-28 15:07 井泉 閱讀(738) | 評論 (0)編輯 收藏

.NET Compact Framework 2.0下調(diào)用EnumWindows(Callback方式) 轉(zhuǎn)

發(fā)過一篇文章是.net cf 1.x實現(xiàn)EnumWindows,因為.net cf 1.x不支持Callback方式,所以實現(xiàn)起來比較繁瑣,而且效率不高。.net cf 2.0中就不同了,已經(jīng)加入了的對Callback的支持了,所以我們就可以調(diào)用EnumWindows這個API函數(shù)來遍歷所有的窗口了,下面是我寫的 一個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 下調(diào)試通過!

posted @ 2008-10-24 16:40 井泉 閱讀(613) | 評論 (1)編輯 收藏

7個網(wǎng)絡(luò)愛好者必裝的Firefox插件 轉(zhuǎn)

以下插件均適用于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或者突破一些防盜鏈。關(guān)于Referer XSS的可以參考利用雅虎站長工具跨站給管理員掛馬
下載:https://addons.mozilla.org/zh-CN/firefox/addon/953

4.Live HTTP Headers  記錄本地的Get和Post數(shù)據(jù),并可修改數(shù)據(jù)后重新提交。
下載:https://addons.mozilla.org/zh-CN/firefox/addon/3829

5.  Poster   用來Post和Get數(shù)據(jù)。
下載: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 井泉 閱讀(529) | 評論 (1)編輯 收藏

三款工具助您將 Firefox 瀏覽器變?yōu)槲淦?轉(zhuǎn)

不知屏幕前的你用的是什么瀏覽 器?由于目前針對Internet Explorer的惡意代碼太多,筆者現(xiàn)在常用Firefox搜索東西。喜歡這種開源軟件的理由很簡單:安全并且擁有很多令人愛不釋手的擴展插件,借助于 這些好東東我們可以放心地瀏覽網(wǎng)絡(luò)、接收電子郵件。如今,為Firefox開發(fā)的擴展插件越來越多。下面就具體看看可以讓我們將Firefox變?yōu)橐粋€強 大武器的三大工具。不過,話又說回來,這些擴展程序并非專用于增強Firefox的安全性,但通過它使用起來卻更加方便。

數(shù)據(jù)修改大師Tamper Data

如果你只能為自己的瀏覽安裝一個安全衛(wèi)士,則非“Tamper Data”莫屬。過去,筆者用Paros Proxy 和 Burp Suite來阻止瀏覽器和Web服務(wù)器之間的請求信息和響應(yīng)。現(xiàn)在這些任務(wù)可以借助于Firefox和Tamper Data實現(xiàn),而無需對代理進行配置。易用就好嘛。

現(xiàn)在用瀏覽器上網(wǎng)沖浪離不開cookie,它是由 Web 頁服務(wù)器置于你硬盤上的一個非常小的文本文件。或許可以這樣講它是你的身份證。雖然它只能由提供它的服務(wù)器來讀取,不過它會泄露你的信息。如果你想訪問的 網(wǎng)站需要一個唯一的cookie,或者說用戶代理,那么筆者建議你在將cookie發(fā)送到Web服務(wù)器之前,先用Tamper Data截獲其請求。然后,對其屬性進行增加、修改等操作,然后再發(fā)送。我們甚至也可以在瀏覽器解釋來自Web服務(wù)器的響應(yīng)之前,對這種響應(yīng)加以修改。我 們覺得安全的則留,不安全的則棄之。豈不妙哉!總之,這是一款對Web應(yīng)用程序的安全感興趣的眾多網(wǎng)友的好工具。

下面給出Tamper Data的日志窗口:(圖1)

圖 1

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

圖 2

安全高于一切:Paros和 Burp

1.Paros

正如其開發(fā)團隊所言,Paros這個程序是為那些需要評估其Web應(yīng)用程序的安全性而設(shè)計的。它用Java語言編寫,并完全免費。通過Paros的代理特性,服務(wù)器和客戶端的所有的HTTP和HTTPS數(shù)據(jù),包括cookies和表單字段,都可以被截獲和修改。

其功能當(dāng)然是不錯了。如捕捉功能,即可以手動捕捉和修改HTTP(和HTTPS)的 請求和響應(yīng);過濾器功能,即對HTTP消息模式進行檢測并發(fā)出警告,幫助用戶處理;掃描功能,即可以掃描一些常見的漏洞;日志功能,即允許用戶查看并檢查 所有的HTTP請求/響應(yīng)內(nèi)容。等等。如下圖3

圖 3

2.Burp套件

其實,Burp套件是一個用于攻擊Web應(yīng)用程序的集成性的平臺。它包含很多工具, 如代理服務(wù)器、圈套程序、入侵程序、轉(zhuǎn)發(fā)程序等,擁有許多接口,可以促進、加強攻擊Web應(yīng)用程序的進程。所有的插件共享Burp的健壯框架,可以處理 HTTP請求、認證、下游代理(downstream proxies)、日志、警告、可擴展性要求等。

Burp套件允許一個攻擊者將手動的和自動的技術(shù)結(jié)合起來,列舉、分析、攻擊并查找web應(yīng)用程序的漏洞。多種Burp工具有效地結(jié)合起來,可以共享信息,并且允許用一種工具找到的漏洞來形成用另外一種工具攻擊的根據(jù)。

其關(guān)鍵特性有:

(1)能夠被動地以一種非入侵方式“圈住”一個應(yīng)用程序,并可使所有的請求都起源于用戶的瀏覽器。

(2)一次單擊就可以在插件之間傳送數(shù)據(jù)請求。

(3)通過IburpExtender接口進行擴展,這也就容許了第三方的代碼擴展Burp套件的功能。由一個插件處理的數(shù)據(jù)可以用任意的方式來影響另外一個插件的行為和結(jié)果。

(4)可以為下游代理、Web、代理認證和日志集中配置。

●Burp套件的下載地址為:http://portswigger.net/suite/

如果你對這些工具感興趣,不妨下載試試。一定會為你帶來驚喜的。

posted @ 2008-10-23 15:24 井泉 閱讀(259) | 評論 (0)編輯 收藏

Building ARM assembly source from within VS 2005 轉(zhuǎn)

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 井泉 閱讀(518) | 評論 (0)編輯 收藏

僅列出標題
共8頁: 1 2 3 4 5 6 7 8 
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧洲精品成人久久奇米网 | 欧美福利精品| 国模私拍一区二区三区| 久久久999精品免费| 欧美国产在线电影| 日韩一本二本av| 国产免费观看久久黄| 性久久久久久久久久久久| 久色成人在线| 一本一本久久a久久精品综合麻豆| 欧美久久成人| 亚洲欧美制服另类日韩| 久久频这里精品99香蕉| 日韩视频不卡| 国产视频精品va久久久久久| 蜜臀a∨国产成人精品| 一区二区三区欧美日韩| 久久这里有精品视频| 日韩视频免费| 国产视频在线一区二区 | 欧美性久久久| 久久久www免费人成黑人精品 | 亚洲美女视频网| 国产色爱av资源综合区| 欧美精品一区二区在线观看| 午夜精品久久久99热福利| 亚洲国产一区二区三区a毛片| 亚洲一区二区高清| 亚洲高清自拍| 国产女人精品视频| 欧美精品在线一区二区| 久久精品久久99精品久久| 宅男在线国产精品| 亚洲第一在线视频| 久久久久在线观看| 先锋亚洲精品| 夜夜嗨av一区二区三区网页| 精品999网站| 国产伦精品一区二区三区| 欧美日韩国产成人精品| 欧美18av| 久久国产色av| 亚洲欧美日韩综合一区| 夜色激情一区二区| 最近中文字幕日韩精品| 老司机67194精品线观看| 性色av一区二区三区| 一本一道久久综合狠狠老精东影业 | 99在线精品视频在线观看| 欧美v日韩v国产v| 久久婷婷久久| 久久久99久久精品女同性| 亚洲一区尤物| 亚洲午夜久久久| 一本一本a久久| 99精品国产在热久久下载| 亚洲国产精品成人综合色在线婷婷| 国产日产欧美一区| 国产日韩高清一区二区三区在线| 国产精品手机视频| 国产精品大全| 欧美视频在线一区| 欧美午夜欧美| 欧美日韩在线免费| 欧美视频一区二区| 国产精品国产三级国产aⅴ浪潮| 欧美日本国产在线| 欧美视频一区二区| 国产精品丝袜91| 国产精品夜夜夜| 国产日本欧美一区二区三区| 国产日韩专区| 影院欧美亚洲| 亚洲人成网站999久久久综合| 亚洲破处大片| 在线午夜精品自拍| 午夜视频在线观看一区| 久久精品国产亚洲5555| 久久综合影音| 亚洲第一在线综合网站| 亚洲精品系列| 亚洲午夜视频在线观看| 亚洲一区视频在线| 久久国产视频网站| 欧美成人嫩草网站| 国产精品成人免费| 国产欧美日本一区视频| 在线日韩av| 99伊人成综合| 欧美亚洲三区| 男人天堂欧美日韩| 日韩视频免费在线| 亚洲欧美日本视频在线观看| 久久精品卡一| 欧美日韩高清在线播放| 国产精品外国| 亚洲欧洲精品成人久久奇米网| 亚洲色图制服丝袜| 久久国产精品久久久| 欧美成人精品不卡视频在线观看| 亚洲日本成人女熟在线观看| 一区二区三区视频在线看| 久久黄色小说| 欧美三级电影精品| 伊人激情综合| 亚洲专区免费| 欧美激情aⅴ一区二区三区| 99国产精品一区| 久久精品国产亚洲a| 欧美精品色网| 国产一区清纯| 亚洲一区精品在线| 你懂的视频欧美| 亚洲午夜激情网站| 欧美成人激情视频免费观看| 国产精品理论片| 日韩亚洲在线| 久久综合国产精品| 亚洲一区二区三区高清不卡| 免费的成人av| 国产午夜精品在线| 一区二区三区蜜桃网| 美女尤物久久精品| 亚洲欧美日韩在线综合| 欧美日韩不卡| 亚洲精品国产日韩| 久久久免费av| 香港成人在线视频| 欧美性色aⅴ视频一区日韩精品| 亚洲国产美女精品久久久久∴| 欧美一区二区女人| 一区二区高清| 欧美精品亚洲| 亚洲欧洲精品一区二区精品久久久| 久久久国产午夜精品| 一区二区三区蜜桃网| 欧美激情欧美狂野欧美精品| 永久555www成人免费| 久久久精品动漫| 亚洲欧美久久久| 欧美天堂亚洲电影院在线观看| 亚洲精品午夜| 亚洲高清免费| 免费在线观看日韩欧美| 依依成人综合视频| 久久久久国产精品厨房| 午夜欧美精品| 国产一区二区电影在线观看| 欧美专区在线观看一区| 中文日韩在线| 国产精品视频网站| 性高湖久久久久久久久| 亚洲午夜久久久久久尤物| 国产精品国产三级国产aⅴ浪潮| 在线中文字幕日韩| 夜夜嗨av一区二区三区网站四季av| 欧美精品日韩三级| 一区二区三区四区五区精品视频 | 国产老女人精品毛片久久| 亚洲在线视频网站| 中文一区二区在线观看| 欧美日韩在线影院| 亚洲女人小视频在线观看| 亚洲性人人天天夜夜摸| 国产精品三级视频| 欧美一区二区三区免费在线看| 亚洲伊人伊色伊影伊综合网| 国产美女一区| 狂野欧美激情性xxxx| 久久国产精品黑丝| 亚洲电影自拍| 91久久精品日日躁夜夜躁国产| 欧美精品福利视频| 亚洲一级在线观看| 午夜精品视频在线| 在线观看精品视频| 最新亚洲电影| 国产精品嫩草影院一区二区| 久久久久久国产精品mv| 久色成人在线| 一区二区三区四区在线| 亚洲综合另类| 亚洲承认在线| 日韩视频一区二区三区在线播放| 国产精品大片wwwwww| 久久人人爽人人爽爽久久| 嫩草国产精品入口| 亚洲综合视频一区| 久久成人在线| 99视频一区二区| 欧美影院一区| 夜色激情一区二区| 性8sex亚洲区入口| 亚洲免费大片| 欧美在线视频免费观看| 亚洲乱码日产精品bd| 亚洲欧美在线一区二区| 亚洲久久在线| 亚洲女同精品视频| 媚黑女一区二区|