So-net無料ブログ作成
検索選択

NtOpenFile [CodeTips]

今回はWindows ネイティブAPIのNtOpenFile関数を使ってファイルをオープンする処理の例です。

ネイティブAPIを呼び出すので、WDK(Windows Driver Kit)を使って、コマンドプロンプトで実行できるモジュールを作成します。今ではVisualStudioと結合されているWDKですが、ここではスタンドアロンで環境を用意できるWindows 7のWDKを使います。

Windows Driver Kit Version 7.1.0

ソースファイル名 'ntopen.cpp'
// ntopen.cpp
// This sample code is opens file using native api function.
// I have built using the Windows 7 WDK (7600.16385.1).
//
#include <ntifs.h>
#include <stdio.h>
#include <locale.h>

// undefined native APIs
EXTERN_C
VOID
NTAPI
RtlSetLastWin32Error(
    ULONG ErrorCode
    );

EXTERN_C
ULONG
NTAPI
RtlGetLastWin32Error(
    VOID
    );

//
// open file by NT namespace
//
HANDLE _open_file(HANDLE hRoot,LPCWSTR FilePath,
            ULONG DesiredAccess,ULONG ShareAccess,ULONG OpenOptions)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    IO_STATUS_BLOCK IoStatus = {0};
    UNICODE_STRING NtPathName;
    NTSTATUS Status;
    HANDLE hFile = NULL;

    RtlInitUnicodeString(&NtPathName,FilePath);

    InitializeObjectAttributes(&ObjectAttributes,&NtPathName,0,hRoot,NULL);

    Status = NtOpenFile(
                    &hFile,
                    DesiredAccess,
                    &ObjectAttributes,
                    &IoStatus,
                    ShareAccess,
                    OpenOptions
                    );

    // Substitute from Win32 error code mechanism.
    RtlSetLastWin32Error(Status);

    return hFile;
}

//
// wmain()
//
int __cdecl wmain(int argc, WCHAR* argv[]) 
{
    _wsetlocale(LC_ALL,L"");

    if( argc < 2 )
    {
        wprintf(L"parameter required.\n");
        return -1;
    }

    HANDLE hFile;
    hFile = _open_file(NULL,argv[1],
                FILE_READ_DATA|FILE_READ_ATTRIBUTES|SYNCHRONIZE,
                FILE_SHARE_READ|FILE_SHARE_WRITE,
                FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_ALERT);

    if( hFile != NULL ) 
    {
        // To do something...
        wprintf(L"open succeeded.\n");

        NtClose(hFile);
    }
    else
    {
        wprintf(L"error : 0x%08X\n",RtlGetLastWin32Error());
    }

    return 0;
}

WDKでビルドする為に必要なsourcesファイルとmakefileも示しておきます。これらをソースファイルと同じディレクトリに置き、buildコマンドでビルドします。

ファイル名 'sources'
TARGETTYPE=PROGRAM
TARGETNAME=ntopen
TARGETPATH=obj
UMTYPE=console
UMENTRY=wmain

_NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINXP)

INCLUDES=$(DDK_INC_PATH)

USE_MSVCRT=1

SOURCES=\
	ntopen.cpp

LINKLIBS=\
	$(DDK_LIB_PATH)\ntdll.lib


ファイル名 'makefile'
!INCLUDE $(NTMAKEENV)\makefile.def


実行例
C:>ntopen \Device\HarddiskVolume2\windows\system32\notepad.exe
open succeeded.

C:>ntopen \??\C:\windows\system32\notepad.exe
open succeeded.


実行時にオープンするファイルの完全のパスをパラメータとして指定します。

NtOpenFileを使っているので、パスはWin32形式やMS-DOSドライブではなく、NTのオブジェクトネームスペースを使います。ドライブ名が割り当てられている場合は、ドライブパスのプリフィックスに'\??\'を付ける書式が指定し易いでしょう。

この例はオープンするだけで何もしません。取得できたファイルハンドルを使ってファイルを読み書きしたり情報を取得したりしてみてください。また、NtOpenFileの引数の詳細はmsdnなどで公開されていますので、いろいろ試すこともできます(ドキュメントではカーネルモードでの名称ZwOpenFileとして公開されています)。

msdn : ZwOpenFile

nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:[必須]
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

Facebook コメント

トラックバック 0

この記事のトラックバックURL:
※言及リンクのないトラックバックは受信されません。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。