Win32 API 日本語リファレンス
ホームNetworking.WinInet › InternetReadFile

InternetReadFile

関数
開いたインターネットハンドルからデータを読み取る。
DLLWININET.dll呼出規約winapiSetLastErrorあり対応OSWindows 2000 以降

シグネチャ

// WININET.dll
#include <windows.h>

BOOL InternetReadFile(
    void* hFile,
    void* lpBuffer,
    DWORD dwNumberOfBytesToRead,
    DWORD* lpdwNumberOfBytesRead
);

パラメーター

名前方向説明
hFilevoid*inInternetOpenUrlFtpOpenFile、 または HttpOpenRequest の前回の呼び出しで返されたハンドル。
lpBuffervoid*outデータを受け取るバッファーへのポインター。
dwNumberOfBytesToReadDWORDin読み取るバイト数。
lpdwNumberOfBytesReadDWORD*out読み取られたバイト数を受け取る変数へのポインター。 InternetReadFile は、処理やエラーチェックを行う前にこの値をゼロに設定します。

戻り値の型: BOOL

公式ドキュメント

InternetOpenUrl、FtpOpenFile、または HttpOpenRequest 関数で開いたハンドルからデータを読み取ります。

戻り値

成功した場合は TRUE を、それ以外の場合は FALSE を返します。拡張エラー情報を取得するには、 GetLastError を呼び出します。アプリケーションは必要に応じて InternetGetLastResponseInfo を使用することもできます。

解説(Remarks)

InternetReadFile は、いくつかの例外を除き、基盤となる ReadFile 関数とほぼ同様に動作します。通常、 InternetReadFileHINTERNET ハンドルからデータを連続したバイトストリームとして取得します。各 InternetReadFile 呼び出しで読み取るデータ量は dwNumberOfBytesToRead パラメーターで指定し、データは lpBuffer パラメーターで返されます。通常の読み取りでは、ファイルの終端に達するまで、各 InternetReadFile 呼び出しで指定された dwNumberOfBytesToRead 分のデータを取得します。すべてのデータを確実に取得するには、関数が TRUE を返し、かつ lpdwNumberOfBytesRead パラメーターがゼロになるまで、アプリケーションは InternetReadFile 関数を呼び出し続ける必要があります。これは、要求されたデータがキャッシュに書き込まれる場合に特に重要です。そうしないとキャッシュが正しく更新されず、ダウンロードされたファイルがキャッシュにコミットされないためです。なお、元のデータストリームを開く要求で INTERNET_FLAG_NO_CACHE_WRITE フラグを設定していない限り、キャッシュは自動的に行われます。

アプリケーションが InternetOpenUrl を使用してハンドルを取得した場合、WinINet はインターネットからの読み取りをアプリケーションにとって容易にするため、すべてのデータをファイルのダウンロードのように見せようとします。FTP ファイルディレクトリの一覧などの一部の種類の情報については、 InternetReadFile によって返されるデータを HTML ストリームに変換します。この変換は行単位で行われます。たとえば、FTP ディレクトリの一覧を 1 行の HTML に変換し、その HTML をアプリケーションに返すことができます。

WinINet は、HTML を lpBuffer バッファーに 1 行ずつ書き込もうとします。アプリケーションのバッファーが、生成された HTML の少なくとも 1 行を収めるには小さすぎる場合、より大きなバッファーが必要であることをアプリケーションに示すため、エラーコード ERROR_INSUFFICIENT_BUFFER が返されます。また、変換された行がバッファーを完全に満たさない場合もあるため、 InternetReadFile は要求されたよりも少ないデータを lpBuffer に格納して返ることがあります。後続の読み取りで、変換されたすべての HTML が取得されます。アプリケーションは、前述のとおり、すべてのデータが取得されたことを再度確認する必要があります。

WinINet API の他のすべての側面と同様に、この関数を DllMain 内、またはグローバルオブジェクトのコンストラクターやデストラクター内から安全に呼び出すことはできません。

非同期で実行している場合、InternetReadFile の呼び出しでトランザクションが完了しなかったときは FALSE を返し、続いて GetLastError を呼び出すと ERROR_IO_PENDING が返されます。トランザクションが完了すると、前回の InternetSetStatusCallback の呼び出しで指定された InternetStatusCallbackINTERNET_STATUS_REQUEST_COMPLETE とともに呼び出されます。

注意 WinINet はサーバー実装をサポートしていません。また、サービスから使用しないでください。サーバー実装やサービスでは、Microsoft Windows HTTP Services (WinHTTP) を使用してください。
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// WININET.dll
#include <windows.h>

BOOL InternetReadFile(
    void* hFile,
    void* lpBuffer,
    DWORD dwNumberOfBytesToRead,
    DWORD* lpdwNumberOfBytesRead
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WININET.dll", SetLastError = true, ExactSpelling = true)]
static extern bool InternetReadFile(
    IntPtr hFile,   // void*
    IntPtr lpBuffer,   // void* out
    uint dwNumberOfBytesToRead,   // DWORD
    out uint lpdwNumberOfBytesRead   // DWORD* out
);
<DllImport("WININET.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function InternetReadFile(
    hFile As IntPtr,   ' void*
    lpBuffer As IntPtr,   ' void* out
    dwNumberOfBytesToRead As UInteger,   ' DWORD
    <Out> ByRef lpdwNumberOfBytesRead As UInteger   ' DWORD* out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' hFile : void*
' lpBuffer : void* out
' dwNumberOfBytesToRead : DWORD
' lpdwNumberOfBytesRead : DWORD* out
Declare PtrSafe Function InternetReadFile Lib "wininet" ( _
    ByVal hFile As LongPtr, _
    ByVal lpBuffer As LongPtr, _
    ByVal dwNumberOfBytesToRead As Long, _
    ByRef lpdwNumberOfBytesRead As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

InternetReadFile = ctypes.windll.wininet.InternetReadFile
InternetReadFile.restype = wintypes.BOOL
InternetReadFile.argtypes = [
    ctypes.POINTER(None),  # hFile : void*
    ctypes.POINTER(None),  # lpBuffer : void* out
    wintypes.DWORD,  # dwNumberOfBytesToRead : DWORD
    ctypes.POINTER(wintypes.DWORD),  # lpdwNumberOfBytesRead : DWORD* out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('WININET.dll')
InternetReadFile = Fiddle::Function.new(
  lib['InternetReadFile'],
  [
    Fiddle::TYPE_VOIDP,  # hFile : void*
    Fiddle::TYPE_VOIDP,  # lpBuffer : void* out
    -Fiddle::TYPE_INT,  # dwNumberOfBytesToRead : DWORD
    Fiddle::TYPE_VOIDP,  # lpdwNumberOfBytesRead : DWORD* out
  ],
  Fiddle::TYPE_INT)
#[link(name = "wininet")]
extern "system" {
    fn InternetReadFile(
        hFile: *mut (),  // void*
        lpBuffer: *mut (),  // void* out
        dwNumberOfBytesToRead: u32,  // DWORD
        lpdwNumberOfBytesRead: *mut u32  // DWORD* out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("WININET.dll", SetLastError = true)]
public static extern bool InternetReadFile(IntPtr hFile, IntPtr lpBuffer, uint dwNumberOfBytesToRead, out uint lpdwNumberOfBytesRead);
"@
$api = Add-Type -MemberDefinition $sig -Name 'WININET_InternetReadFile' -Namespace Win32 -PassThru
# $api::InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
#uselib "WININET.dll"
#func global InternetReadFile "InternetReadFile" sptr, sptr, sptr, sptr
; InternetReadFile hFile, lpBuffer, dwNumberOfBytesToRead, varptr(lpdwNumberOfBytesRead)   ; 戻り値は stat
; hFile : void* -> "sptr"
; lpBuffer : void* out -> "sptr"
; dwNumberOfBytesToRead : DWORD -> "sptr"
; lpdwNumberOfBytesRead : DWORD* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "WININET.dll"
#cfunc global InternetReadFile "InternetReadFile" sptr, sptr, int, var
; res = InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
; hFile : void* -> "sptr"
; lpBuffer : void* out -> "sptr"
; dwNumberOfBytesToRead : DWORD -> "int"
; lpdwNumberOfBytesRead : DWORD* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; BOOL InternetReadFile(void* hFile, void* lpBuffer, DWORD dwNumberOfBytesToRead, DWORD* lpdwNumberOfBytesRead)
#uselib "WININET.dll"
#cfunc global InternetReadFile "InternetReadFile" intptr, intptr, int, var
; res = InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
; hFile : void* -> "intptr"
; lpBuffer : void* out -> "intptr"
; dwNumberOfBytesToRead : DWORD -> "int"
; lpdwNumberOfBytesRead : DWORD* out -> "var"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	wininet = windows.NewLazySystemDLL("WININET.dll")
	procInternetReadFile = wininet.NewProc("InternetReadFile")
)

// hFile (void*), lpBuffer (void* out), dwNumberOfBytesToRead (DWORD), lpdwNumberOfBytesRead (DWORD* out)
r1, _, err := procInternetReadFile.Call(
	uintptr(hFile),
	uintptr(lpBuffer),
	uintptr(dwNumberOfBytesToRead),
	uintptr(lpdwNumberOfBytesRead),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function InternetReadFile(
  hFile: Pointer;   // void*
  lpBuffer: Pointer;   // void* out
  dwNumberOfBytesToRead: DWORD;   // DWORD
  lpdwNumberOfBytesRead: Pointer   // DWORD* out
): BOOL; stdcall;
  external 'WININET.dll' name 'InternetReadFile';
result := DllCall("WININET\InternetReadFile"
    , "Ptr", hFile   ; void*
    , "Ptr", lpBuffer   ; void* out
    , "UInt", dwNumberOfBytesToRead   ; DWORD
    , "Ptr", lpdwNumberOfBytesRead   ; DWORD* out
    , "Int")   ; return: BOOL
●InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead) = DLL("WININET.dll", "bool InternetReadFile(void*, void*, dword, void*)")
# 呼び出し: InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
# hFile : void* -> "void*"
# lpBuffer : void* out -> "void*"
# dwNumberOfBytesToRead : DWORD -> "dword"
# lpdwNumberOfBytesRead : DWORD* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "wininet" fn InternetReadFile(
    hFile: ?*anyopaque, // void*
    lpBuffer: ?*anyopaque, // void* out
    dwNumberOfBytesToRead: u32, // DWORD
    lpdwNumberOfBytesRead: [*c]u32 // DWORD* out
) callconv(std.os.windows.WINAPI) i32;
proc InternetReadFile(
    hFile: pointer,  # void*
    lpBuffer: pointer,  # void* out
    dwNumberOfBytesToRead: uint32,  # DWORD
    lpdwNumberOfBytesRead: ptr uint32  # DWORD* out
): int32 {.importc: "InternetReadFile", stdcall, dynlib: "WININET.dll".}
pragma(lib, "wininet");
extern(Windows)
int InternetReadFile(
    void* hFile,   // void*
    void* lpBuffer,   // void* out
    uint dwNumberOfBytesToRead,   // DWORD
    uint* lpdwNumberOfBytesRead   // DWORD* out
);
ccall((:InternetReadFile, "WININET.dll"), stdcall, Int32,
      (Ptr{Cvoid}, Ptr{Cvoid}, UInt32, Ptr{UInt32}),
      hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
# hFile : void* -> Ptr{Cvoid}
# lpBuffer : void* out -> Ptr{Cvoid}
# dwNumberOfBytesToRead : DWORD -> UInt32
# lpdwNumberOfBytesRead : DWORD* out -> Ptr{UInt32}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t InternetReadFile(
    void* hFile,
    void* lpBuffer,
    uint32_t dwNumberOfBytesToRead,
    uint32_t* lpdwNumberOfBytesRead);
]]
local wininet = ffi.load("wininet")
-- wininet.InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
-- hFile : void*
-- lpBuffer : void* out
-- dwNumberOfBytesToRead : DWORD
-- lpdwNumberOfBytesRead : DWORD* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('WININET.dll');
const InternetReadFile = lib.func('__stdcall', 'InternetReadFile', 'int32_t', ['void *', 'void *', 'uint32_t', 'uint32_t *']);
// InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
// hFile : void* -> 'void *'
// lpBuffer : void* out -> 'void *'
// dwNumberOfBytesToRead : DWORD -> 'uint32_t'
// lpdwNumberOfBytesRead : DWORD* out -> 'uint32_t *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("WININET.dll", {
  InternetReadFile: { parameters: ["pointer", "pointer", "u32", "pointer"], result: "i32" },
});
// lib.symbols.InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead)
// hFile : void* -> "pointer"
// lpBuffer : void* out -> "pointer"
// dwNumberOfBytesToRead : DWORD -> "u32"
// lpdwNumberOfBytesRead : DWORD* out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t InternetReadFile(
    void* hFile,
    void* lpBuffer,
    uint32_t dwNumberOfBytesToRead,
    uint32_t* lpdwNumberOfBytesRead);
C, "WININET.dll");
// $ffi->InternetReadFile(hFile, lpBuffer, dwNumberOfBytesToRead, lpdwNumberOfBytesRead);
// hFile : void*
// lpBuffer : void* out
// dwNumberOfBytesToRead : DWORD
// lpdwNumberOfBytesRead : DWORD* out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Wininet extends StdCallLibrary {
    Wininet INSTANCE = Native.load("wininet", Wininet.class);
    boolean InternetReadFile(
        Pointer hFile,   // void*
        Pointer lpBuffer,   // void* out
        int dwNumberOfBytesToRead,   // DWORD
        IntByReference lpdwNumberOfBytesRead   // DWORD* out
    );
}
@[Link("wininet")]
lib LibWININET
  fun InternetReadFile = InternetReadFile(
    hFile : Void*,   # void*
    lpBuffer : Void*,   # void* out
    dwNumberOfBytesToRead : UInt32,   # DWORD
    lpdwNumberOfBytesRead : UInt32*   # DWORD* out
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef InternetReadFileNative = Int32 Function(Pointer<Void>, Pointer<Void>, Uint32, Pointer<Uint32>);
typedef InternetReadFileDart = int Function(Pointer<Void>, Pointer<Void>, int, Pointer<Uint32>);
final InternetReadFile = DynamicLibrary.open('WININET.dll')
    .lookupFunction<InternetReadFileNative, InternetReadFileDart>('InternetReadFile');
// hFile : void* -> Pointer<Void>
// lpBuffer : void* out -> Pointer<Void>
// dwNumberOfBytesToRead : DWORD -> Uint32
// lpdwNumberOfBytesRead : DWORD* out -> Pointer<Uint32>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function InternetReadFile(
  hFile: Pointer;   // void*
  lpBuffer: Pointer;   // void* out
  dwNumberOfBytesToRead: DWORD;   // DWORD
  lpdwNumberOfBytesRead: Pointer   // DWORD* out
): BOOL; stdcall;
  external 'WININET.dll' name 'InternetReadFile';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "InternetReadFile"
  c_InternetReadFile :: Ptr () -> Ptr () -> Word32 -> Ptr Word32 -> IO CInt
-- hFile : void* -> Ptr ()
-- lpBuffer : void* out -> Ptr ()
-- dwNumberOfBytesToRead : DWORD -> Word32
-- lpdwNumberOfBytesRead : DWORD* out -> Ptr Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let internetreadfile =
  foreign "InternetReadFile"
    ((ptr void) @-> (ptr void) @-> uint32_t @-> (ptr uint32_t) @-> returning int32_t)
(* hFile : void* -> (ptr void) *)
(* lpBuffer : void* out -> (ptr void) *)
(* dwNumberOfBytesToRead : DWORD -> uint32_t *)
(* lpdwNumberOfBytesRead : DWORD* out -> (ptr uint32_t) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library wininet (t "WININET.dll"))
(cffi:use-foreign-library wininet)

(cffi:defcfun ("InternetReadFile" internet-read-file :convention :stdcall) :int32
  (h-file :pointer)   ; void*
  (lp-buffer :pointer)   ; void* out
  (dw-number-of-bytes-to-read :uint32)   ; DWORD
  (lpdw-number-of-bytes-read :pointer))   ; DWORD* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $InternetReadFile = Win32::API::More->new('WININET',
    'BOOL InternetReadFile(LPVOID hFile, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPVOID lpdwNumberOfBytesRead)');
# my $ret = $InternetReadFile->Call($hFile, $lpBuffer, $dwNumberOfBytesToRead, $lpdwNumberOfBytesRead);
# hFile : void* -> LPVOID
# lpBuffer : void* out -> LPVOID
# dwNumberOfBytesToRead : DWORD -> DWORD
# lpdwNumberOfBytesRead : DWORD* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

類似 API