FC2ブログ

[Win32API][Winsock][Development]WSAGetLastError()

 Windowsのネイティブで開発をしている(.NET 上のCLRではなく)と、エラーコードが、「誰の」エラーコードであるかということを理解していないとデバッグに困ってしまう。
 WSAGetLastError()は、このSocket APIを呼び出したスレッド上でのWinsockエラーコードのようだ。つまり内部的には、TLS(Thread LocalStorage)にエラーコードを保存しているように振舞っている。
 これは、プロセス単位のエラーコードではないということだ。スレッドAの上でWinsockエラーが起きた直後に、スレッドB上でWSAGetLastError()を実行しても、信頼できるエラーコードが取得できないということを意味する。
 .NET FrameworkやMFCのメッセージマップを使っていたり、スレッドプールをバリバリ使っているようなプログラムだと、とくに問題になりそうな予感がする。
 エラー処理をする際には、「誰が」エラーを引き起こしたのか、「誰の」エラーコードを参照したのか、ということを意識しなければならない。スレッド構成が複雑なプログラムであればなおのことこれは難しい問題となるだろう。
 だからこそ、マルチスレッドは難しい、と言われるゆえんなのだが。
スポンサーサイト



more...

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

GetStdHandle(STD_OUTPUT_HANDLE)とprintf

 ちょっと検証用にprintfの出力を物理ファイルにリダイレクトしてみようと思ったが、どうもそう単純な話でもないらしい。
 SetStdHandle()を単純に実行するだけでは標準出力を物理ファイルに振り向けることはできないことがあるようだ。
 原因はいまいちよくわからないが、printf()が内部的にstdoutのハンドルを複製していて、SetStdhandle()の影響を受けないように保護しているのかもしれない。
 まあ、stdoutをソケットにリダイレクトすれば、ネットワーク経由でコンソール操作がだだもれになるわけだし、セキュリティの観点からはそういう実装のほうが正しいのかも。(環境はXP SP3、開発はVS2008)

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

ディレクトリの存在チェック

ディレクトリの存在チェック (株式会社ディア Dear inc.)

 CreateFile(Ex)でディレクトリの存在チェックをするサンプルですが、オプション引数にFILE_FLAG_BACKUP_SEMANTICSという値を使用しています。
 この引数をOPEN_EXISTINGにすると失敗することがある(ACCESS_DENIED)のですが、その原因は何なんでしょうか。
 まあ、ACCESS_DENIEDであれば、ディレクトリが存在することだけは間違いないのですが。
 何か、別のプロセスがアクセスしっぱなしなんですかねぇ。

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win32API]Get/SetEnvironmentVariable()

 Win32API経由で環境変数を設定する方法として知られているのが、Get/SetEnvironmentVariable()。しかし、これらのAPIはプログラム内でのみ変更が有効になるもので、システム環境変数には影響が及ばない。
 そのため、PATH環境変数を設定して外部プログラムからのDLLサーチパスを追加する、といったことをやりたいときには、この方法は使えない。
 ならば、どうしなければならないかというと、システム環境変数はレジストリの中に実体があるので、レジストリに対して変更を行えばいい。
 ちなみに、レジストリ上のパスは HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win32]STATUS_STACK_BUFFER_OVERRUN

 0xC~はシステム例外、0xE~はアプリケーション例外(アプリケーション製作者が独自に定義した例外)であり、エラールックアップなどではコードの意味が調べられない。
 というわけで、備忘録をかねて、自分が発見したWindowsの例外コードと調査結果については、当ブログでも継続的に取り扱っていこうと考えている。

more...

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Development][VC++] 意図的にデッドロックを発生させる

 変なコードですが、擬似的な親子二つのプロセスを立ち上げて、一方が他方のプロセスを監視しています(実際にプロセス間に親子関係があるわけではありません)。
 先に疑似親プロセスを起動し、続いて疑似子プロセスを起動します。
 疑似親子プロセスの間で意図的にデッドロックを発生させています。そのため、疑似子プロセスが消滅(このままだとCTRL+Cなどで意図的に停止しないといけませんが)すると、デッドロック状態が解消され疑似親プロセスも正常終了します。

 これら二つのプロセスはどちらも同じ実行ファイルから起動します。疑似親プロセスの起動には/pスイッチを使用して、疑似子プロセスの起動には/cスイッチを使用します。

 これだけではほとんど意味はありませんが、常時疑似子プロセスを監視して、疑似子プロセスが消滅した時点で疑似親プロセスに何らかの処理をさせることができます。(こういう場合、ふつうはプロセスのハンドルを取得すると思いますがね・笑)

 最後に、疑似親プロセスが、500msecごとにWaitをLoopさせていますが、疑似子プロセスがミューテックスハンドルを握り込んだまま消滅するとオブジェクトの状態が怪しくなるためです。当初は疑似子プロセスが終了したところでWAIT_ABANDONEDが返ってくると予想していたのですが、私がタメしたXP SP3上ではそのまま疑似親プロセスがロックされていました。

 ふつうはシステムオブジェクトをロックしたままプロセスを終了させるような凶悪なことはせず、この場合は疑似子プロセスのプロセスハンドルをWaitすると思います。その場合、疑似子プロセスが終了したところでロックが解除され、WAIT_OBJECT_0が返ってくるでしょう。

more...

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Other]209/8/28 第6回UMTPモデリング技術セミナー、参加レポート

 UMTP Japan - UMTPモデリング技術セミナー 第6回開催(2009-08-28)のご案内

に、参加してきました。

 会場はオフィス内でしたので、周辺写真等は撮影しておりません(もっとも、有名なビル街のまっただ中ですので、場所の特定は簡単ですね)。

 当日は快晴で、とても暑い一日でした。開始時間が13:30ということで、すこし前までお昼の時間帯でしたから、エキナカから地下道を通ってビルに到着するまで、かなりの人混みだったことを覚えています。

 このセミナーは、主にUMTP L2合格者を対象としたものだそうで、中心としているテーマは要件定義でした。その中で、UMLを拡張したsysMLという表記法をご紹介いただきました。

more...

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Windows][Visual Studio 2008][VC++]signal(CRT)

 VC++環境でsignalの動作を確認してみた。
 サンプルは、無限ループでひたすらコンソールに”.”を標準出力する。

 いろいろ試してみてわかったこと。

  • CTRL+CでSIGINTを発生させても、すぐにプロセスは終了しなかった
    (SIGINTを受信するとコンソールに”SIGINT\n”と表示されるが、その後も”.”が何個か表示されていた)
    (追記:どうやら、stdio.hで定義された入出力関数はシグナルに同期しない、つまりシグナル関数内では使用禁止の模様)
  • [タスク マネージャ]の[プロセス]タブから強制終了すると、SIGTERMを受信する前にプロセスが消滅するっぽい?
  • taskkill /fすると、SIGTERMを受信する前にプロセスが消滅するっぽい?

 強制終了がハンドリングできないところを見ると、上記の下二つは9番(SIGKILL)を投げていると考えればいいのでしょうか。

more...

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win23API] メールスロット動作検証サンプル

 メールスロットのサンプル。

 「セッション 0 の分離」対応に使えるかどうかを検証するために使用。

 使い方は、ビルドモジュールのインスタンスを二つ立ち上げる。/sスイッチを付けた方がメールスロットサーバで、/cスイッチを付けた方はクライアントとして動作する。

 /sをつけて実行したメールスロットサーバは、クライアントからの書き込みを待機する。

 /cを付けて実行したクライアントは、"Test."という文字列をポストする。

 メールスロットサーバは、ポストを受信したらポストされた内容(=Test.")をコンソールに表示する。

more...

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Visual C++ 2008] (const)char*と_TCHAR*

 Visual C++ 2008でちょっとものを作っていたとき、なんとなく引っかかってしまったことがあったのでメモ。

more...

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win][Dev][VC++] VC++ではbad_allocは非標準

 (追記:2009/3/19)以下の記述は、VC6までの話です。



 ロベールのC++教室 - 第49章 破壊と創造 -

 まさかVC++でtry~catchを使う気になるとは思ってなかったので、これまであんまり調べてなかった。
 VC++は標準でbad_allocを投げないなんて。
 理解できないわけではないんだよね。Windowsネイティブの例外処理はSEHが基本だから。
 でも、new/deleteしてる関数内だとSEHを使えないという制約があるのだ。

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win32API] Windowsサービスの実装方法について、ちょっと調べてみたこと

 main関数は,ServiceMain関数をSCMに登録した後で制御を返さなければなりません。

(マーシャル ブレイン (著), ロン リーブス (著), Marshall Brain (原著), Ron Reeves (原著), ドキュメントシステム (翻訳) 、『Win32システムサービスプログラミング改訂版』p.463,ピアソンエデュケーション)

 これって、main関数のライフラインはStartServiceCtrlDispatcher呼び出しと一致するということかな?

 一方、

 このスレッドを開始すると,その後でServiceMain関数は,一般的にイベントを待機する状態に入ります。ServiceMain関数は,サービスが停止されるときまで,制御を返してはいけません。ServiceMain関数が制御を返した場合,サービスが停止されるので,SCMは再びServiceMain関数を呼び出してサービスを開始します。

(マーシャル ブレイン (著), ロン リーブス (著), Marshall Brain (原著), Ron Reeves (原著), ドキュメントシステム (翻訳) 、『Win32システムサービスプログラミング改訂版』p.464,ピアソンエデュケーション)

とあるが、これってSERVICE_STOPするまで、SCMは何度でもServiceMainをコールするということでしょうかね?


 ちなみに、SERVICE_CONTROL_SHUTDOWNのコントロール処理中に、Handler関数内でWAITをかけると、サービスがハングする。これはガチ。

 最初見たとき、なんじゃこりゃって思った。そんな実装ですた。

 あと、サービス停止中にHandlerでWAITかけると、「タスクマネージャ」上ではプロセスが消えてるのにSCM的には「停止処理中」になっているような?






Win32システムサービスプログラミング (Windows2000 Technologies Series)Win32システムサービスプログラミング (Windows2000 Technologies Series)
(2002/01)
マーシャル ブレインロン リーブス

商品詳細を見る

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win32] ERROR_SEM_TIMEOUT

 セマフォとか全然使ってないのにセマフォのせいみたいなエラーコードが出ることがある。
呼び出したシステムコールが内部的にセマフォを使ってるせいだと思うけど。

WN0016 - WebCom Wiki

> CreateMailslot() で MAILSLOT_WAIT_FOREVER を指定しても WtireFileで err番号 #121 ERROR_SEM_TIMEOUT が出る。
> メールスロットが一杯になった場合に エラー番号 121 (ERROR_SEM_TIMEOUT) が返される。

Windows XP ベースのコンピュータの SCardEstablishContext 関数を呼び出すことと、エラー メッセージ0x79-ERROR_SEM_TIMEOUT- セマフォのタイムアウト期間が切れて

> SCardEstablishContext 関数が、スマート カード サービスに接続します。 この現象は、Smart Card サービス準備ができておよび接続のリッスンが前に、アプリケーションが SCardEstablishContext 関数を呼び出す場合に発生することがあります。

 スマートカードサービスが接続を受け付けられるようになる前に、クライアントから接続をかけてきたってことか?

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Win32] CRITICAL_SECTIONをロックしたスレッドが、ロックしたままTermしたら

#pragma once

#include <windows.h>
#include <process.h>
#include <TCHAR.H>
#include <stdio.h>


// *******************************************************
void ThreadFunc0();
void ThreadFunc1();
void WriteLog(LPSTR);

// *******************************************************
CRITICAL_SECTION    cs;
CRITICAL_SECTION    cs_cons;
HANDLE    hEvent[2]={INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};


int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE  hThread[2]={INVALID_HANDLE_VALUE,INVALID_HANDLE_VALUE};
    DWORD   dwThreadId[2]={0,0};

    ZeroMemory(&cs,sizeof(CRITICAL_SECTION));
    ZeroMemory(&cs_cons,sizeof(CRITICAL_SECTION));

    __try{
        ::InitializeCriticalSection(&cs);
        ::InitializeCriticalSection(&cs_cons);
        WriteLog("Test starts.");

        hEvent[0]=CreateEvent(NULL,TRUE,FALSE,NULL);
        hEvent[1]=CreateEvent(NULL,TRUE,FALSE,NULL);

        hThread[0]=(HANDLE)_beginthreadex( NULL,
                         0,
                         (unsigned int (__stdcall *)(void *))ThreadFunc0,
                         NULL,
                         TRUE,
                         (unsigned int *)&dwThreadId[0]);
        hThread[1]=(HANDLE)_beginthreadex( NULL,
                         0,
                         (unsigned int (__stdcall *)(void *))ThreadFunc1,
                         NULL,
                         TRUE,
                         (unsigned int *)&dwThreadId[1]);

        ::WaitForMultipleObjects(2,hEvent,TRUE,INFINITE);
        Sleep(1000);
        WriteLog("Therad0 starts to quit.");
        ::PostThreadMessage(dwThreadId[0],WM_QUIT,0,0);

        ::WaitForMultipleObjects(2,hThread,TRUE,INFINITE);
    }
    __finally{
        ::DeleteCriticalSection(&cs);
        ::DeleteCriticalSection(&cs_cons);
        WriteLog("Test ends.");
    } 
    return 0;
}

// *******************************************************
LRESULT WINAPI WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
    LRESULT lResult=NULL;
    char    cMessage[1024];


    ZeroMemory(cMessage,1024);
    switch(msg)
    {
        case WM_GETMINMAXINFO:
        case WM_NCCREATE:
        case WM_NCCALCSIZE:
        case WM_CREATE:
            // ウィンドウ生成時に発生するいつものメッセージ。読み飛ばし 
              lResult=::DefWindowProc(hWnd,msg,wParam,lParam); 
            break; 
        case WM_NCDESTROY:
            // ウィンドウ破棄時に発生するいつものメッセージ。読み飛ばし 
              lResult=::DefWindowProc(hWnd,msg,wParam,lParam); 
            break; 
        case WM_QUIT:
            WriteLog("Received \"WM_QUIT\"."); 
              lResult=::DefWindowProc(hWnd,msg,wParam,lParam); 
            break; 
        default:
            sprintf(cMessage,"Received 0x\"%08X\".",msg);
            WriteLog(cMessage);
            lResult=::DefWindowProc(hWnd,msg,wParam,lParam); 
            break; 
    }; 

    return lResult;
}

HWND OpenThreadWindow(LPSTR WindowName)
{
    WNDCLASSEX    wcex;


    ZeroMemory(&wcex,sizeof(WNDCLASSEX));

    wcex.cbSize=sizeof(WNDCLASSEX);
    wcex.lpfnWndProc=WndProc;
    wcex.lpszClassName=WindowName;
    wcex.hInstance=GetModuleHandle(NULL);

    RegisterClassEx(&wcex); 
    return  CreateWindow( WindowName, 
                          WindowName, 
                            0, 
                            CW_USEDEFAULT, 
                            0, 
                            CW_USEDEFAULT, 
                            0, 
                            HWND_MESSAGE, 
                            NULL, 
                            GetModuleHandle(NULL), 
                            NULL);
}

// ******************************************************* 
void ThreadFunc0()
{
    MSG        msg;
    HWND    hWnd=NULL;
    int        iMsgResult=0;


    WriteLog("Thread0 starts.");
    ::EnterCriticalSection(&cs);    // CriticalSectionを取得する 
    SetEvent(hEvent[0]);            // Thread0の起動終了を通知 

    OpenThreadWindow("ThreadFunc0");
    PeekMessage(&msg,hWnd,0,0,PM_NOREMOVE); 

    do{
        iMsgResult=GetMessage(&msg,hWnd,0,0); 
        if(iMsgResult==-1)
        {
            DWORD    dwErrorCode=GetLastError();
            abort();
        } else if(iMsgResult>0)
        {
            //    何かする。
        }

    }while(iMsgResult>0); 
// ::LeaveCriticalSection(&cs); // わざとLeaveしてない 

    DestroyWindow(hWnd);

    WriteLog("Thread0 ends.");


void ThreadFunc1()
{
    ::WaitForSingleObject(hEvent[0],INFINITE);  // Thread0の起動を待つ 
    WriteLog("Thread1 starts.");
    SetEvent(hEvent[1]);           // Thread1の起動終了を通知 

    ::EnterCriticalSection(&cs);
    ::LeaveCriticalSection(&cs);
    WriteLog("Thread1 ends.");



// *************************************************************************** 
void WriteLog(LPSTR log)
{
    SYSTEMTIME    lpTime;

    ZeroMemory(&lpTime,sizeof(SYSTEMTIME));
    GetSystemTime(&lpTime);

    ::EnterCriticalSection(&cs_cons);
    printf( "[%02d:%02d:%02d.%04d] ",
            lpTime.wHour,
            lpTime.wMinute,
            lpTime.wSecond,
            lpTime.wMilliseconds);
    printf( "PID : %d, TID : %d, %s\n",
            GetCurrentProcessId(),
            GetCurrentThreadId(),
            log);
    ::LeaveCriticalSection(&cs_cons);
}

more...

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証

[Development][VC++] RaiseException()で任意のデータを渡す

#include <TCHAR.H>
#include <windows.h>
#include <stdio.h>


int _tmain(int argc, _TCHAR* argv[])
{
_EXCEPTION_POINTERS* info;
const char Ixa[]="その命、神に返しなさい."; // 例外ブロックに通知したい値(1)
int Nagosan=753; // 例外ブロックに通知したい値(2)
PVOID Rising[15]; // RaiseException()に渡す引数リストの実体


__try{
// イ・ク・サ・カ・イ・ザ・ー、フィ・ス・ト・オ・ン
Rising[0]=(PVOID)&Ixa; // 引数リストを作成中(1)
Rising[1]=(PVOID)&Nagosan; // 引数リストを作成中(2)
Rising[2]=NULL; // 引数リストを作成中(3)

// イ・ク・サ・カ・リ・バ・ー、ラ・イ・ズ・ア・ッ・プ
RaiseException(0xE000001,0,2,(const ULONG_PTR *)&Rising);
}
__except(info=GetExceptionInformation(),EXCEPTION_EXECUTE_HANDLER)
{
// ラ・イ・ジ・ン・グ
char buffer[1024];
::ZeroMemory(buffer,sizeof(buffer));
strcpy(buffer,(char*)info->ExceptionRecord->ExceptionInformation[0]);

printf("%s by %d",buffer,(int)info->ExceptionRecord->ExceptionInformation[1]);
DWORD exception_code=info->ExceptionRecord->ExceptionCode;
}


return 0;
}

theme : プログラミング
genre : コンピュータ

FC2ブックマーク | この記事をokyuuへインポート | このエントリーを含むはてなブックマーク | ニフティクリップへ追加 | この記事をクリップ! | イザ!ブックマーク | POOKMARK Airlinesに登録する | del.icio.us |
動作未検証 | | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証 | 動作未検証
カレンダー
10 | 2019/11 | 12
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
最近の記事
月別アーカイブ
カテゴリー
ブログ内検索
RSSフィード
リンク
いろいろリンクボタン
埋め込みe-Words