baf21b26cd87f40a5593ac99a4b7c7f19db9cad2
[reactos.git] / lib / kernel32 / file / iocompl.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/file/iocompl.c
6  * PURPOSE:         Io Completion functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  * UPDATE HISTORY:
9  *                  Created 01/11/98
10  */
11
12 #include <k32.h>
13
14
15 #include <kernel32/error.h>
16
17 /*
18  * @implemented
19  */
20 HANDLE
21 STDCALL
22 CreateIoCompletionPort(
23     HANDLE FileHandle,
24     HANDLE ExistingCompletionPort,
25     DWORD CompletionKey,
26     DWORD NumberOfConcurrentThreads
27     )
28 {
29    HANDLE CompletionPort = NULL;
30    NTSTATUS errCode;
31    FILE_COMPLETION_INFORMATION CompletionInformation;
32    IO_STATUS_BLOCK IoStatusBlock;
33
34    if ( ExistingCompletionPort == NULL && FileHandle == INVALID_HANDLE_VALUE ) 
35    {
36       SetLastErrorByStatus (STATUS_INVALID_PARAMETER);
37       return FALSE;
38    }
39
40    if ( ExistingCompletionPort != NULL ) 
41    {
42       CompletionPort = ExistingCompletionPort;
43    }
44    else 
45    {
46
47       errCode = NtCreateIoCompletion(&CompletionPort,
48                                      IO_COMPLETION_ALL_ACCESS,
49                                      NULL,//ObjectAttributes
50                                      NumberOfConcurrentThreads);
51
52       if (!NT_SUCCESS(errCode) ) 
53       {
54          SetLastErrorByStatus (errCode);
55          return FALSE;
56       }
57
58    }
59    
60    if ( FileHandle != INVALID_HANDLE_VALUE ) 
61    {
62       CompletionInformation.IoCompletionHandle = CompletionPort;
63       CompletionInformation.CompletionKey  = CompletionKey;
64
65       errCode = NtSetInformationFile(FileHandle, 
66                                      &IoStatusBlock,
67                                      &CompletionInformation,
68                                      sizeof(FILE_COMPLETION_INFORMATION),
69                                      FileCompletionInformation);
70
71       if ( !NT_SUCCESS(errCode) ) 
72       {
73          if ( ExistingCompletionPort == NULL )
74          {
75             NtClose(CompletionPort);
76          }
77    
78          SetLastErrorByStatus (errCode);
79          return FALSE;
80       }
81    }
82
83    return CompletionPort;
84 }
85
86
87 /*
88  * @implemented
89  */
90 WINBOOL
91 STDCALL
92 GetQueuedCompletionStatus(
93    HANDLE CompletionHandle,
94    LPDWORD lpNumberOfBytesTransferred,
95    LPDWORD lpCompletionKey,
96    LPOVERLAPPED *lpOverlapped,
97    DWORD dwMilliseconds
98    )
99 {
100    NTSTATUS errCode;
101    IO_STATUS_BLOCK IoStatus;
102    LARGE_INTEGER Interval;
103
104    if (!lpNumberOfBytesTransferred||!lpCompletionKey||!lpOverlapped)
105    {
106       return ERROR_INVALID_PARAMETER;
107    }
108
109    if (dwMilliseconds != INFINITE)
110    {
111       /*
112        * System time units are 100 nanoseconds (a nanosecond is a billionth of
113        * a second).
114        */
115       Interval.QuadPart = dwMilliseconds;
116       Interval.QuadPart = -(Interval.QuadPart * 10000);
117    }  
118    else
119    {
120       /* Approximately 292000 years hence */
121       Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
122    }
123
124    errCode = NtRemoveIoCompletion(CompletionHandle,
125                                   lpCompletionKey,
126                                   lpNumberOfBytesTransferred,
127                                   &IoStatus,
128                                   &Interval);
129
130    if (!NT_SUCCESS(errCode) ) {
131       *lpOverlapped = NULL;
132       SetLastErrorByStatus(errCode);
133       return FALSE;
134    }
135
136    *lpOverlapped = (LPOVERLAPPED)IoStatus.Information;
137
138    if (!NT_SUCCESS(IoStatus.Status)){
139       //failed io operation
140       SetLastErrorByStatus (IoStatus.Status);
141       return FALSE;
142    }
143
144    return TRUE;
145
146 }
147
148
149 /*
150  * @implemented
151  */
152 WINBOOL
153 STDCALL
154 PostQueuedCompletionStatus(
155    HANDLE CompletionHandle,
156    DWORD dwNumberOfBytesTransferred,
157    DWORD dwCompletionKey,
158    LPOVERLAPPED lpOverlapped
159    )
160 {
161    NTSTATUS errCode;
162
163    errCode = NtSetIoCompletion(CompletionHandle,  
164                                dwCompletionKey, 
165                                dwNumberOfBytesTransferred,//CompletionValue 
166                                0,                         //IoStatusBlock->Status
167                                (ULONG)lpOverlapped );     //IoStatusBlock->Information
168
169    if ( !NT_SUCCESS(errCode) ) 
170    {
171       SetLastErrorByStatus (errCode);
172       return FALSE;
173    }
174    return TRUE;
175 }
176
177
178 /*
179  * @implemented
180  */
181 BOOL STDCALL
182 CancelIo(HANDLE hFile)
183 {
184   IO_STATUS_BLOCK IoStatusBlock;
185   NTSTATUS Status;
186
187   Status = NtCancelIoFile(hFile,
188                           &IoStatusBlock);
189   if (!NT_SUCCESS(Status))
190     {
191       SetLastErrorByStatus(Status);
192       return(FALSE);
193     }
194
195   return(TRUE);
196 }
197
198 /* EOF */