Windows NT driverek fejleszt - PowerPoint PPT Presentation

About This Presentation
Title:

Windows NT driverek fejleszt

Description:

Title: Windows NT architekt ra Author: Sandor LUKACS Last modified by: robu Created Date: 10/22/2006 11:49:27 AM Document presentation format: On-screen Show – PowerPoint PPT presentation

Number of Views:36
Avg rating:3.0/5.0
Slides: 34
Provided by: Sandor7
Category:

less

Transcript and Presenter's Notes

Title: Windows NT driverek fejleszt


1
Windows NT driverek fejlesztése Egyszeru
driverek készítése
9
  • eloadás
  • dr. Robu Judit
  • szeminárium
  • drd. Lukács Sándor

2006
2
Driver objektumok (DRIVER_OBJECT)
  • typedef struct _DRIVER_OBJECT
  • // The following links all of the devices
    created by a single driver together on a
  • // list, and the Flags word provides an
    extensible flag location for driver objects.
  • PDEVICE_OBJECT DeviceObject // de DEVICE
    objektum lista elso eleme
  • ULONG Flags
  • // The following section describes where the
    driver is loaded.
  • PVOID DriverStart // a driver
    bináris képének kezdocíme
  • ULONG DriverSize
  • PVOID DriverSection
  • ...
  • // The driver name field is used by the error
    log thread
  • // determine the name of the driver that an
    I/O request is/was bound.
  • UNICODE_STRING DriverName
  • ...
  • // The following section describes the entry
    points to this particular driver.
  • PDRIVER_INITIALIZE DriverInit //
    DriverEntry kezdocíme

3
Device objektumok (DEVICE_OBJECT)
  • typedef struct _DEVICE_OBJECT
  • LONG ReferenceCount
  • struct _DRIVER_OBJECT DriverObject
  • struct _DEVICE_OBJECT NextDevice
  • ...
  • struct _IRP CurrentIrp // csak StartIo
    rutinnal párhuzamosan használt,
  • // NULL ha nincs
    aktuális IRP feldolgozás alatt
  • ...
  • ULONG Flags // DO_BUFFERED_IO,
    DO_DIRECT_IO, - I/O típus

  • DO_BUS_ENUMERATED_DEVICE, - PDO

  • DO_DEVICE_INITIALIZING, ... - inicializálás
    aktív
  • ULONG Characteristics //
    FILE_DEVICE_IS_MOUNTED,

  • FILE_READ_ONLY_DEVICE,

  • FILE_REMOVABLE_MEDIA,

  • FILE_VIRTUAL_VOLUME, ...
  • ...
  • PVOID DeviceExtension // programozó
    által definált
  • DEVICE_TYPE DeviceType //
    FILE_DEVICE_CD_ROM, FILE_DEVICE_DISK,

  • FILE_DEVICE_FILE_SYSTEM,

4
Standard I/O muvelet feldolgozás
DISPATCH
COMPLETION
  • (az ábra Walter Oney Programming the Microsoft
    Windows Driver Model, Microsoft Press, 1999
    alapján készült)

5
I/O muvelet típusok
  • több I/O típus van
  • állomány alapú / jellegu I/O
  • támogatja a Read / Write / Seek stb. jellegu
    muveleteket
  • nagyon állományrendszer specifikus
  • device / FS kontroll I/O kérések
  • explicit, eszköz specifikus I/O kérések küldése
  • vannak FS specifikus kérések is
  • további kommunikációs csatornák
  • Filter Manager specifikus kommunikációs portok
  • szinkron / aszinkron támogatás, kétírányú
    kezdeményezés
  • speciális esetben osztott memória
  • minden driver az elvárásoknak és a támogatott
    eszköz tulajdonságainak megfeleloen támogat egy
    vagy több típust

6
IRP dispatch kérések 1
  • IRP_MJ_CREATE ZwCreateFile
  • device objektumok vagy állományok megnyítása
  • egy FILE_OBJECT objektumot inicializál
  • IRP_MJ_CLEANUP ZwClose, 1 lépés
  • a FILE_OBJECT-re mutató utolsó handle bezárásakor
    hívódik meg
  • IRP_MJ_CLOSE ZwClose, 2 lépés
  • az utolsó I/O muvelet elvégzése után hívódik meg
  • IRP_MJ_READ ZwReadFile
  • IRP_MJ_WRITE ZwWriteFile
  • állományok vagy lemezegységek írása / olvasása
  • IRP_MJ_FLUSH_BUFFERS ZwFlushBuffersFile
  • egy ilyen kérés esetén egy driver kiurití az
    össze átementi cachet
  • IRP_MJ_DIRECTORY_CONTROL ZwQueryDirectoryFile
  • könyvtár lekérdezések esetén hívódik meg (pl.
    FindFirst, FindNext)

7
IRP dispatch kérések 2
  • IRP_MJ_QUERY_INFORMATION ZwQueryInformationFile
  • IRP_MJ_SET_INFORMATION ZwSetInformationFile
  • állományokkal kapcsolatos információk lekérdezése
    / beállítása
  • FileBasicInformation create time, file
    attributes etc.
  • FileNameInformation állomány neve
  • FileStandardInformation állomány mérete, hard
    linkek száma, könyvtár-e?, az állomány törlödik-e
    bezárások (delete pending)
  • FilePositionInformation állomány pozíció
  • IRP_MJ_QUERY_VOLUME_INFORMATION
    ZwQueryVolumeInformationFile
  • IRP_MJ_SET_VOLUME_INFORMATION
    ZwSetVolumeInformationFile
  • lemezegységekkel kapcsolatos információk
    lekérdezése / beállítása
  • FileFsDeviceInformation CD-ROM, HDD, floppy,
    read-only stb.
  • FileFsFullSizeInformation a lemezegység mérete,
    szabad blokkok stb.
  • FileFsVolumeInformation lemezegyés neve, serial
    number stb.
  • IRP_MJ_FILE_SYSTEM_CONTROL ZwFsControlFile
  • IRP_MJ_DEVICE_CONTROL ZwDeviceIoControlFile
  • FSCTL és IOCTL kérések végrehajtása
  • speciális kérések/parancsok a hardver egységek és
    FS driverek számára(pl. IOCTL_CDROM_DISC_INFO,
    IOCTL_CDROM_GET_DRIVE_GEOMETRY,
    IOCTL_CDROM_RAW_READ, FSCTL_DISMOUNT_VOLUME,
    FSCTL_SET_SPARSE, FSCTL_GET_VOLUME_BITMAP,
    FSCTL_MOVE_FILE etc.)

8
Driver, device és I/O stack függoség
COMPLETION
DISPATCH
  • (az ábra Walter Oney Programming the Microsoft
    Windows Driver Model, Microsoft Press, 1999
    alapján készült)

9
IRP paraméterek 1
  • typedef struct _IO_STACK_LOCATION
  • UCHAR MajorFunction
  • UCHAR MinorFunction
  • UCHAR Flags
  • UCHAR Control
  • union
  • // System service parameters for
    NtCreateFile
  • struct
  • PIO_SECURITY_CONTEXT SecurityContext
  • ULONG Options
  • USHORT POINTER_ALIGNMENT
    FileAttributes
  • USHORT ShareAccess
  • ULONG POINTER_ALIGNMENT EaLength
  • Create
  • // System service parameters for
    NtReadFile
  • struct
  • ULONG Length
  • ULONG POINTER_ALIGNMENT Key
  • LARGE_INTEGER ByteOffset

10
IRP paraméterek 2
  • // Save a pointer to this device driver's
    device object for this request
  • // so it can be passed to the completion
    routine if needed.
  • PDEVICE_OBJECT DeviceObject
  • // The following location contains a pointer
    to the file object for this request.
  • PFILE_OBJECT FileObject
  • // The following routine is invoked depending
    on the flags in the above flags field.
  • PIO_COMPLETION_ROUTINE CompletionRoutine
  • // The following is used to store the address
    of the context parameter
  • // that should be passed to the
    CompletionRoutine.
  • PVOID Context
  • IO_STACK_LOCATION, PIO_STACK_LOCATION
  • egy IRP feldolgozása során minden driver számára
    le van foglalva egy IRPSP struktúra
  • irpSp IoGetCurrentIrpStackLocation(Irp) a
    jelenlegi driver szintjén lévo IRPSP struktúra
    címe

11
I/O bufferek kezelése
  • egy I/O kérés végrehajtársa különbözo processz
    kontextusokban történhet
  • pl. egy READ/WRITE kérés végrehajtása a hívó fél
    (gyakran user módbeli alkalmazás) kontextusában
    kezdodig, majd miután a hardver végrehajtotta a
    kérést és egy megaszkítást generál, egy
    tetszoleges rendszer kontextusban folyatódik és
    fejezodik be
  • a legtöbb esetben a memória mutatók, bufferek
    stb. NEM használhatók tetszoleges kontextusban
  • három alapveto I/O buffer kezelési módszer
  • Buffered I/O az I/O manager elkészít egy, a
    hívó bufferrel azonos méretu NonPaged rendszer
    buffert és ebbe másolja az adatokat átmenetileg
  • READ esetén a completion rutinban kernel
    nonpaged ? alkalmazás
  • WRITE esetén a dispatch turinban alkalmazás ?
    kernel nonpaged
  • Direct I/O az I/O manager rögzíti a memóriába
    az alkalmazás bufferének megfelelo fizikai
    lapokat, elkészít egy, ezeket a lapokat leíró
    MDL-t, majd ezt az MDL-t továbbítja a drivernek
    amely tetszolegesen betukrözi a lapokat a
    rendszer virtuális címterületére (új laptábla
    bemenetekkel)
  • Neither I/O az I/O manager nem végez semmilyen
    buffer és cím átalakítást, közvetlenül a hívó
    buffer eredeti címét adja át a drivernek

12
Buffered I/O
  • ha DEVICE_OBJECT Flags mezoje tartalmazza a
    DO_BUFFERED_IO-t
  • ha az IOCTL kód buffered I/O-t kér

13
Direct I/O, PIO feldolgozással
  • ha DEVICE_OBJECT Flags mezoje tartalmazza a
    DO_DIRECT_IO-t
  • ha az IOCTL kód buffered I/O-t kér
  • PIO programmed I/O

14
Direct I/O, DMA feldolgozással
  • ha DEVICE_OBJECT Flags mezoje tartalmazza a
    DO_DIRECT_IO-t
  • ha az IOCTL kód buffered I/O-t kér
  • DMA direct memory access

15
IRP_MJ_CREATE
  • amikor egy új állományt vagy könyvtárat hozunk
    létre,vagy egy már létezo állományt, könyvtárat,
    partíciót vagy eszközt akarunk megnyítni
  • paraméterek
  • DeviceObject a device amelyen a muveletet végre
    kell hajtani
  • Options IrpSp-gtParameters.Create.Options
    FILE_VALID_OPTION_FLAGS
  • Disposition (IrpSp-gtParameters.Create.Options
    gtgt 24) 0xFF
  • CREATE_NEW, OPEN_EXISTING, CREATE_ALWAYS, ...
  • IrpSp-gtParameters.Create.FileAttributes
  • IrpSp-gtParameters.Create.ShareAccess
  • IrpSp-gtFileObject-gtFileName
  • IrpSp-gtFileObject-gtRelatedFileObject ha nem
    abszolút path-el dolgozunk
  • IrpSp-gtFileObject-gtFlags
  • FO_SYNCHRONOUS_IO, FO_NO_INTERMEDIATE_BUFFERING
  • kimenet
  • IrpSp-gtFileObject-gtFsContext, IrpSp-gtFileObject-gtF
    sContext2
  • FS driver specifikus, bármilyen saját információ
    vagy pointer
  • Irp-gtIoStatus.Status
  • STATUS_SUCCESS, STATUS_OBJECT_NAME_NOT_FOUND,
    STATUS_ACCESS_DENIED
  • Irp-gtIoStatus.Information
  • FILE_OPENED, FILE_DOES_NOT_EXIST

16
IRP_MJ_CLEANUP
  • amikor egy file objektum handle referencia
    számlálója nullára vált (az utolsó handelt is
    bezárátk)
  • paraméterek
  • DeviceObject a device amelyen a muveletet végre
    kell hajtani
  • IrpSp-gtFileObject
  • az IrpSp-gtFileObject-gtFileName NEM érvényes
  • IrpSp-gtFileObject-gtFsContext, IrpSp-gtFileObject-gtF
    sContext2
  • kimenet
  • IrpSp-gtFileObject-gtFlags FO_CLEANUP_COMPLETE
  • ezt mindig el kell végezni a cleanup végén
  • Irp-gtIoStatus.Status
  • STATUS_SUCCESS
  • Irp-gtIoStatus.Information
  • 0

17
IRP_MJ_CLOSE
  • amikor egy file objektum referencia számlálója
    nullára vált (már egyetlen pointer vagy handel
    sem mutat a file objektumra)
  • paraméterek
  • DeviceObject a device amelyen a muveletet végre
    kell hajtani
  • IrpSp-gtFileObject
  • az IrpSp-gtFileObject-gtFileName NEM érvényes
  • IrpSp-gtFileObject-gtFsContext, IrpSp-gtFileObject-gtF
    sContext2
  • kimenet
  • fel kell szabadítani minden file specifikus
    eroforrást
  • ezt mindig el kell végezni a close végén
  • Irp-gtIoStatus.Status
  • STATUS_SUCCESS
  • Irp-gtIoStatus.Information
  • 0

18
IRP_MJ_READ
  • több aleset van, ezek közül az IRP_MN_xxx
    kódokkal teszünk különbséget
  • IRP_MN_NORMAL klasszikus olvasás
  • paraméterek
  • DeviceObject a device amelyen a muveletet végre
    kell hajtani
  • IrpSp-gtFileObject-gtFsContext, IrpSp-gtFileObject-gtF
    sContext2
  • IrpSp-gtParameters.Read.ByteOffset.QuadPart
  • IrpSp-gtParameters.Read.Length
  • Irp-gtAssociatedIrp.SystemBuffer BUFFERED I/O
    esetén
  • Irp-gtMdlAddress DIRECT I/O esetén
  • Irp-gtUserBuffer NEITHER I/O esetén
  • kimenet
  • Irp-gtIoStatus.Status
  • Irp-gtIoStatus.Information BytesReaded
  • sikeres végrehajtás és FO_SYNCHRONOUS_IO kérés
    esetén mindig updatelni kell az aktuális file
    pozíciót
  • IrpSp-gtFileObject-gtCurrentByteOffset.QuadPart

19
IRP_MJ_DEVICE_CONTROL
  • a legtöbb esetben egy felhasználói alkalmazás
    vagy egy 3rd party kernel komponens IOCTL kérése
    estén küldodik
  • paramétrek
  • DeviceObject a device amelyen a muveletet végre
    kell hajtani
  • Irp-gtAssociatedIrp.SystemBuffer BUFFERED I/O
    esetén
  • Irp-gtMdlAddress DIRECT I/O esetén
  • Irp-gtUserBuffer NEITHER I/O esetén
  • IrpSp-gtParameters.DeviceIoControl.InputBufferLengt
    h
  • IrpSp-gtParameters.DeviceIoControl.IoControlCode
  • IrpSp-gtParameters.DeviceIoControl.OutputBufferLeng
    th
  • kimenet
  • Irp-gtIoStatus.Status
  • Irp-gtIoStatus.Information kimeneti adatok mérete

20
Egy összeadó driver implementálása
  • minimális driver, amely...
  • létrehoz egy device objektumot
  • ezt elérhetové teszi a user mód számára is
    szimbolikus link által
  • megengedi a device objektum megnyítását (CREATE),
    azért, hogy lehessen kéreseket küldeni a driver
    fele egy handel-nek a segítségével
  • természetesen szükséges CLEANUP és CLOSE is
  • a device specifikus I/O kommunikációt
    felhasználva (IOCTL) elfogad és végrehajt egy
    speciális kérést
  • két bemeno egész értéket összead, és az eredményt
    egy kimeneti értékbe helyezi
  • az adatok átadását BUFFERED I/O módszerrel oldjuk
    meg

21
Általános definíciók
  • // driver and device name
  • define DRIVER_NAME "sumdriver.sys"
  • define DEVICE_NAME L"\\sumdriver"
  • define DOS_DEVICE_NAME L"\\dosdevices\\sumdev
    ice"
  • // driver specific I/O structures
  • typedef struct _IOCTL_SUM
  • __int32 a
  • __int32 b
  • __int32 c
  • IOCTL_SUM, PIOCTL_SUM
  • // driver global data
  • extern DRV_GLOBAL_DATA DrvGlobalData
  • // IOCTL codes
  • define IOCTL_DRV_SUM_TWO_INTS
    \
  • (ULONG)CTL_CODE( FILE_DEVICE_UNKNOWN,
    0x0981, METHOD_BUFFERED,
    FILE_ANY_ACCESS)

typedef struct _DRV_GLOBAL_DATA
PDRIVER_OBJECT DriverObject
PDEVICE_OBJECT DeviceObject
UNICODE_STRING DeviceName UNICODE_STRING
DosDeviceName DRV_GLOBAL_DATA,
PDRV_GLOBAL_DATA
22
DriverEntry 1
  • NTSTATUS DriverEntry(
  • __in PDRIVER_OBJECT DriverObject, __in
    PUNICODE_STRING RegistryPath )
  • ...
  • // clear global data area
  • RtlZeroMemory(DrvGlobalData,
    sizeof(DRV_GLOBAL_DATA))
  • // get DriverObject into global data
  • DrvGlobalData.DriverObject DriverObject
  • // setup unload routine
  • DrvGlobalData.DriverObject-gtDriverUnload
    DriverUnload
  • // initialize the dispatch entry points
  • DriverObject-gtMajorFunctionIRP_MJ_CREATE
    Drv_MJ_CREATE
  • DriverObject-gtMajorFunctionIRP_MJ_CLEANUP
    Drv_MJ_CLEANUP
  • DriverObject-gtMajorFunctionIRP_MJ_CLOSE
    Drv_MJ_CLOSE
  • DriverObject-gtMajorFunctionIRP_MJ_DEVICE_CONT
    ROL Drv_MJ_DEVICE_CONTROL

23
DriverEntry 2
  • // create the main device object
  • RtlInitUnicodeString((DrvGlobalData.DeviceName),
    DEVICE_NAME)
  • status IoCreateDevice(DriverObject, 0,
    DrvGlobalData.DeviceName,
  • FILE_DEVICE_UNKNOWN, 0, FALSE,
    DrvGlobalData.DeviceObject)
  • if (!NT_SUCCESS(status))
  • ExKdPrint((" DriverEntry - error loading
    driver\n"))
  • return status
  • // clear DO_DEVICE_INITIALIZING
  • DrvGlobalData.DeviceObject-gtFlags
    DO_DEVICE_INITIALIZING
  • // create symbolic link
  • RtlInitUnicodeString((DrvGlobalData.DosDeviceName
    ), DOS_DEVICE_NAME)
  • IoCreateSymbolicLink((DrvGlobalData.DosDeviceName
    ), (DrvGlobalData.DeviceName))
  • return status

24
DriverUnload
  • VOID DriverUnload(__in PDRIVER_OBJECT
    DriverObject)
  • UNREFERENCED_PARAMETER(DriverObject)
  • ExKdPrint(("try to unload driver\n"))
  • // break into kernel debugger if enabled
  • // DbgBreakPointWithStatus(0x12345678)
  • // delete symbolic link
  • IoDeleteSymbolicLink((DrvGlobalData.DosDevice
    Name))
  • // delete main device object
  • IoDeleteDevice(DrvGlobalData.DeviceObject)
  • ExKdPrint(("...GAME OVER!\n"))

25
Drv_MJ_xxx vázCREATE, CLEANUP, CLOSE,
DEVICE_CONTROL számára
  • NTSTATUS Drv_MJ_xxx(__in PDEVICE_OBJECT
    DeviceObject, __in PIRP Irp)
  • NTSTATUS status
  • PIO_STACK_LOCATION irpSp
  • status STATUS_UNSUCCESSFUL
  • irpSp IoGetCurrentIrpStackLocation(Irp)
  • __try
  • __try
  • // ... ide kerul az IRP MJ specifikus
    kód
  • status STATUS_SUCCESS
    // csak ha sikeres volt a végrehajtás
  • __except(EXCEPTION_EXECUTE_HANDLER)
  • status GetExceptionCode()
  • ExKdPrint(("EXCEPTION - d - s -
    d\n", status, __FILE__, __LINE__))
  • __finally

26
Drv_MJ_xxx kódok 1
  • Drv_MJ_CREATE
  • // request to open the device?
  • if (DeviceObject DrvGlobalData.DeviceObject)
  • Irp-gtIoStatus.Information FILE_OPENED
  • status STATUS_SUCCESS
  • else
  • Irp-gtIoStatus.Information
    FILE_DOES_NOT_EXIST
  • status STATUS_OBJECT_NAME_NOT_FOUND
  • Drv_MJ_CLEANUP
  • // signal on FOB that we have done our work
  • fileObject irpSp-gtFileObject
  • fileObject-gtFlags FO_CLEANUP_COMPLETE
  • status STATUS_SUCCESS

27
Drv_MJ_xxx kódok 2
  • Drv_MJ_CLOSE
  • status STATUS_SUCCESS
  • Drv_MJ_DEVICE_CONTROL
  • ioctlCode irpSp-gtParameters.DeviceIoControl.IoCo
    ntrolCode
  • switch (ioctlCode)
  • case IOCTL_DRV_SUM_TWO_INTS
  • status Drv_IOCTL_DRV_SUM_TWO_INTS(Irp,
    irpSp)
  • break
  • default
  • ExKdPrint(("unhandled IOCTL 0x08x\n",
    ioctlCode))
  • status STATUS_INVALID_PARAMETER

28
Drv_IOCTL_DRV_SUM_TWO_INTS
  • NTSTATUS Drv_IOCTL_DRV_SUM_TWO_INTS(__in PIRP
    Irp, __in PIO_STACK_LOCATION IrpSp)
  • NTSTATUS status
  • PIOCTL_SUM sum
  • UNREFERENCED_PARAMETER(IrpSp)
  • ExKdPrint(("Drv_IOCTL_DRV_SUM_TWO_INTS\n"))
  • status STATUS_UNSUCCESSFUL
  • // get user buffer pointer
  • sum (PIOCTL_SUM)(Irp-gtAssociatedIrp.SystemBu
    ffer)
  • // calculate sum and set return data length
    and status
  • sum-gtc sum-gta sum-gtb
  • Irp-gtIoStatus.Information
    sizeof(IOCTL_SUM)
  • status STATUS_SUCCESS
  • return status

29
User módbeli vezérlo alkalmazás 1
  • define FILE_DEVICE_UNKNOWN
    0x00000022
  • define METHOD_BUFFERED 0
  • define FILE_ANY_ACCESS 0
  • define FILE_READ_ACCESS (0x0001) //
    file pipe
  • define FILE_WRITE_ACCESS (0x0002) //
    file pipe
  • define CTL_CODE(DeviceType, Function, Method,
    Access) \
  • (((DeviceType)ltlt16)((Access)ltlt14)((Function)
    ltlt2)(Method))
  • define IOCTL_DRV_SUM_TWO_INTS
    \
  • (ULONG)CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0981,
    \
  • METHOD_BUFFERED,
    FILE_ANY_ACCESS)
  • typedef struct _IOCTL_SUM // driver
    specifikus adat struktúra amely
  • // segítségével
    történik a kommunikáció a
  • __int32 a // driver és az
    alkalmazás között
  • __int32 b // a kérés és
    válasz számára lehet
  • __int32 c // két különbözo
    struktúrát is használni
  • IOCTL_SUM, PIOCTL_SUM

30
User módbeli vezérlo alkalmazás 2
  • // global kernel device handle
  • HANDLE DevHandle
  • ...
  • int main(void)
  • __int32 a,b,c
  • DevHandle CreateFile(L"\\\\?\\sumdevice",
    0, 0, 0,
  • OPEN_EXISTING,
    FILE_FLAG_OVERLAPPED, 0)
  • if (DevHandle INVALID_HANDLE_VALUE)
  • printf("invalid handle, can't open
    device\n")
  • return -1
  • a 10 b 20
  • SumTwoInts(a, b, c)
  • printf("d d d\n", a, b, c)

31
User módbeli vezérlo alkalmazás 3
  • int SumTwoInts(__int32 a, __int32 b, __int32 c)
  • IOCTL_SUM inout // adatstruktúra,
    amelyet a kommunikációra felhasználunk
  • // ez
    mindig azonosan kell legyen deklarálva a driver
    és az
  • inout.a a // alkalmazás
    kódjában
  • inout.b b
  • if (DeviceIoControl(DevHandle,
    IOCTL_DRV_SUM_TWO_INTS,
  • inout, sizeof(IOCTL_SUM), inout,
    sizeof(IOCTL_SUM), b, NULL))
  • // itt
    lehet a BE- és KI-menetnek különbozo buffert
    megadni
  • c inout.c
  • return 1
  • else
  • printf("last error d\n",
    GetLastError())
  • return 0

32
Egy I/O kérés végrehajtása
33
  • Köszönöm a figyelmet!
Write a Comment
User Comments (0)
About PowerShow.com