1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3  *   Copyright (C) 1997 University of Chicago.
4  *   See COPYRIGHT notice in top-level directory.
5  */
6 
7 #include "ad_ntfs.h"
8 
ADIOI_NTFS_ReadContig(ADIO_File fd,void * buf,int count,MPI_Datatype datatype,int file_ptr_type,ADIO_Offset offset,ADIO_Status * status,int * error_code)9 void ADIOI_NTFS_ReadContig(ADIO_File fd, void *buf, int count,
10 			   MPI_Datatype datatype, int file_ptr_type,
11 			   ADIO_Offset offset, ADIO_Status *status,
12 			   int *error_code)
13 {
14     LONG dwTemp;
15     DWORD dwNumRead = 0;
16     int err=-1, datatype_size, len;
17     static char myname[] = "ADIOI_NTFS_ReadContig";
18     OVERLAPPED *pOvl;
19 
20     /* If file pointer is of type ADIO_INDIVIDUAL ignore the offset
21        and use the current location of file pointer */
22     if(file_ptr_type == ADIO_INDIVIDUAL){
23 	offset = fd->fp_ind;
24     }
25 
26     MPI_Type_size(datatype, &datatype_size);
27     len = datatype_size * count;
28 
29     pOvl = (OVERLAPPED *) ADIOI_Calloc(sizeof(OVERLAPPED), 1);
30     if (pOvl == NULL)
31     {
32 	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
33 	    myname, __LINE__, MPI_ERR_IO,
34 	    "**nomem", "**nomem %s", "OVERLAPPED");
35 	return;
36     }
37     pOvl->hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
38     if (pOvl->hEvent == NULL)
39     {
40     char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
41 	err = GetLastError();
42     ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
43 	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
44 	    myname, __LINE__, MPI_ERR_IO,
45 	    "**io", "**io %s", errMsg);
46 	ADIOI_Free(pOvl);
47 	return;
48     }
49     pOvl->Offset = DWORDLOW(offset);
50     pOvl->OffsetHigh = DWORDHIGH(offset);
51 
52     if (file_ptr_type == ADIO_EXPLICIT_OFFSET)
53     {
54 	if (fd->fp_sys_posn != offset)
55 	{
56 	    dwTemp = DWORDHIGH(offset);
57 	    if (SetFilePointer(fd->fd_sys, DWORDLOW(offset), &dwTemp, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
58 	    {
59         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
60 		err = GetLastError();
61         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
62 		if (err != NO_ERROR)
63 		{
64 		    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
65 			myname, __LINE__, MPI_ERR_IO,
66 			"**io", "**io %s", errMsg);
67 		    CloseHandle(pOvl->hEvent);
68 		    ADIOI_Free(pOvl);
69 		    return;
70 		}
71 	    }
72 	}
73 	/*
74 	{
75 	    ADIO_Fcntl_t fcntl_struct;
76 	    int error_code;
77 	    ADIO_Fcntl(fd, ADIO_FCNTL_GET_FSIZE, &fcntl_struct, &error_code);
78 	    printf("File size b: %d\n", fcntl_struct.fsize);
79 	}
80 	printf("ReadFile(%d bytes)\n", len);fflush(stdout);
81 	*/
82 	err = ReadFile(fd->fd_sys, buf, len, &dwNumRead, pOvl);
83 	/* --BEGIN ERROR HANDLING-- */
84 	if (err == FALSE)
85 	{
86         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
87 	    err = GetLastError();
88         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
89 	    switch (err)
90 	    {
91 	    case ERROR_IO_PENDING:
92 		break;
93 	    case ERROR_HANDLE_EOF:
94 		/*printf("EOF error\n");fflush(stdout);*/
95 		SetEvent(pOvl->hEvent);
96 		break;
97 	    default:
98 		*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
99 		    myname, __LINE__, MPI_ERR_IO,
100 		    "**io",
101 		    "**io %s", errMsg);
102 		CloseHandle(pOvl->hEvent);
103 		ADIOI_Free(pOvl);
104 		return;
105 	    }
106 	}
107 	/* --END ERROR HANDLING-- */
108 	err = GetOverlappedResult(fd->fd_sys, pOvl, &dwNumRead, TRUE);
109 	/* --BEGIN ERROR HANDLING-- */
110 	if (err == FALSE)
111 	{
112         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
113 	    err = GetLastError();
114         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
115 	    if (err != ERROR_HANDLE_EOF) /* Ignore EOF errors */
116 	    {
117 		*error_code = MPIO_Err_create_code(MPI_SUCCESS,
118 		    MPIR_ERR_RECOVERABLE, myname,
119 		    __LINE__, MPI_ERR_IO, "**io",
120 		    "**io %s", errMsg);
121 		CloseHandle(pOvl->hEvent);
122 		ADIOI_Free(pOvl);
123 		return;
124 	    }
125 	}
126 	/* --END ERROR HANDLING-- */
127 	if (!CloseHandle(pOvl->hEvent))
128 	{
129         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
130 	    err = GetLastError();
131         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
132 	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
133 		myname, __LINE__, MPI_ERR_IO,
134 		"**io", "**io %s", errMsg);
135 	    CloseHandle(pOvl->hEvent);
136 	    ADIOI_Free(pOvl);
137 	    return;
138 	}
139 	ADIOI_Free(pOvl);
140 
141 	fd->fp_sys_posn = offset + (ADIO_Offset)dwNumRead;
142 	/* individual file pointer not updated */
143     }
144     else
145     {
146 	/* read from curr. location of ind. file pointer */
147 	if (fd->fp_sys_posn != fd->fp_ind)
148 	{
149 	    dwTemp = DWORDHIGH(fd->fp_ind);
150 	    if (SetFilePointer(fd->fd_sys, DWORDLOW(fd->fp_ind), &dwTemp, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
151 	    {
152         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
153 		err = GetLastError();
154         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
155 		if (err != NO_ERROR)
156 		{
157 		    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
158 			myname, __LINE__, MPI_ERR_IO,
159 			"**io", "**io %s", errMsg);
160 		    CloseHandle(pOvl->hEvent);
161 		    ADIOI_Free(pOvl);
162 		    return;
163 		}
164 	    }
165 	}
166 	/*
167 	{
168 	    ADIO_Fcntl_t fcntl_struct;
169 	    int error_code;
170 	    ADIO_Fcntl(fd, ADIO_FCNTL_GET_FSIZE, &fcntl_struct, &error_code);
171 	    printf("File size c: %d\n", fcntl_struct.fsize);
172 	}
173 	printf("ReadFile(%d bytes)\n", len);fflush(stdout);
174 	*/
175 	err = ReadFile(fd->fd_sys, buf, len, &dwNumRead, pOvl);
176 	/* --BEGIN ERROR HANDLING-- */
177 	if (err == FALSE)
178 	{
179         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
180 	    err = GetLastError();
181         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
182 	    switch (err)
183 	    {
184 	    case ERROR_IO_PENDING:
185 		break;
186 	    case ERROR_HANDLE_EOF:
187 		/*printf("EOF error\n");fflush(stdout);*/
188 		SetEvent(pOvl->hEvent);
189 		break;
190 	    default:
191 		*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
192 		    myname, __LINE__, MPI_ERR_IO,
193 		    "**io",
194 		    "**io %s", errMsg);
195 		CloseHandle(pOvl->hEvent);
196 		ADIOI_Free(pOvl);
197 		return;
198 	    }
199 	}
200 	/* --END ERROR HANDLING-- */
201 	err = GetOverlappedResult(fd->fd_sys, pOvl, &dwNumRead, TRUE);
202 	/* --BEGIN ERROR HANDLING-- */
203 	if (err == FALSE)
204 	{
205         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
206 	    err = GetLastError();
207         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
208 	    if (err != ERROR_HANDLE_EOF) /* Ignore EOF errors */
209 	    {
210 		*error_code = MPIO_Err_create_code(MPI_SUCCESS,
211 		    MPIR_ERR_RECOVERABLE, myname,
212 		    __LINE__, MPI_ERR_IO, "**io",
213 		    "**io %s", errMsg);
214 		CloseHandle(pOvl->hEvent);
215 		ADIOI_Free(pOvl);
216 		return;
217 	    }
218 	}
219 	/* --END ERROR HANDLING-- */
220 	if (!CloseHandle(pOvl->hEvent))
221 	{
222         char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
223 	    err = GetLastError();
224         ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
225 	    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
226 		myname, __LINE__, MPI_ERR_IO,
227 		"**io", "**io %s", errMsg);
228 	    ADIOI_Free(pOvl);
229 	    return;
230 	}
231 	ADIOI_Free(pOvl);
232 
233 	fd->fp_ind = fd->fp_ind + (ADIO_Offset)dwNumRead;
234 	fd->fp_sys_posn = fd->fp_ind;
235     }
236 
237 #ifdef HAVE_STATUS_SET_BYTES
238     if (err != FALSE)
239     {
240 	MPIR_Status_set_bytes(status, datatype, dwNumRead);
241     }
242 #endif
243 
244     /* --BEGIN ERROR HANDLING-- */
245     if (err == FALSE)
246     {
247     char errMsg[ADIOI_NTFS_ERR_MSG_MAX];
248 	err = GetLastError();
249     ADIOI_NTFS_Strerror(err, errMsg, ADIOI_NTFS_ERR_MSG_MAX);
250 	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
251 					   myname, __LINE__, MPI_ERR_IO,
252 					   "**io",
253 					   "**io %s", errMsg);
254 	return;
255     }
256     /* --END ERROR HANDLING-- */
257     *error_code = MPI_SUCCESS;
258 }
259