18 #include <ndb_global.h>
20 #include "Win32AsyncFile.hpp"
22 #include <signaldata/FsRef.hpp>
23 #include <signaldata/FsOpenReq.hpp>
24 #include <signaldata/FsReadWriteReq.hpp>
31 Win32AsyncFile::~Win32AsyncFile()
37 Win32AsyncFile::init()
46 m_open_flags = request->par.open.flags;
49 DWORD dwCreationDisposition;
50 DWORD dwDesiredAccess = 0;
51 DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
60 DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS;
61 Uint32
flags = request->par.open.flags;
64 if ((flags & FsOpenReq::OM_CREATE) && (flags & FsOpenReq::OM_TRUNCATE)){
65 dwCreationDisposition = CREATE_ALWAYS;
66 }
else if (flags & FsOpenReq::OM_TRUNCATE){
67 dwCreationDisposition = TRUNCATE_EXISTING;
68 }
else if (flags & (FsOpenReq::OM_CREATE|FsOpenReq::OM_CREATE_IF_NONE)){
69 dwCreationDisposition = CREATE_NEW;
71 dwCreationDisposition = OPEN_EXISTING;
75 case FsOpenReq::OM_READONLY:
76 dwDesiredAccess = GENERIC_READ;
78 case FsOpenReq::OM_WRITEONLY:
79 dwDesiredAccess = GENERIC_WRITE;
81 case FsOpenReq::OM_READWRITE:
82 dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
85 request->error = 1000;
90 hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode,
91 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
93 if(INVALID_HANDLE_VALUE == hFile) {
94 request->error = GetLastError();
95 if(((ERROR_PATH_NOT_FOUND == request->error) || (ERROR_INVALID_NAME == request->error))
96 && (flags & (FsOpenReq::OM_CREATE|FsOpenReq::OM_CREATE_IF_NONE))) {
98 hFile = CreateFile(theFileName.c_str(), dwDesiredAccess, dwShareMode,
99 0, dwCreationDisposition, dwFlagsAndAttributes, 0);
101 if(INVALID_HANDLE_VALUE == hFile)
102 request->error = GetLastError();
111 if (flags & FsOpenReq::OM_INIT)
116 sz.QuadPart= request->par.open.file_size;
118 bzero(buf,
sizeof(buf));
119 while(off.QuadPart < sz.QuadPart)
121 BOOL r= SetFilePointerEx(hFile, off, NULL, FILE_BEGIN);
124 request->error= GetLastError();
128 BOOL bWrite= WriteFile(hFile, buf,
sizeof(buf), &dwWritten, 0);
129 if(!bWrite || dwWritten!=
sizeof(buf))
131 request->error= GetLastError();
133 off.QuadPart+=
sizeof(
buf);
136 BOOL r= SetFilePointerEx(hFile, off, NULL, FILE_BEGIN);
139 request->error= GetLastError();
146 bzero(signal,
sizeof(tmp));
149 Uint32
block = refToMain(request->theUserReference);
150 Uint32 instance = refToInstance(request->theUserReference);
153 sz.QuadPart= request->par.open.file_size;
154 while(off.QuadPart < sz.QuadPart)
156 req->filePointer = 0;
157 req->userPointer = request->theUserPointer;
158 req->numberOfPages = 1;
159 req->varIndex = index++;
160 req->data.pageData[0] = m_page_ptr.i;
163 FsReadWriteReq::FixedLength + 1,
166 Uint32
size = request->par.open.page_size;
167 char* buf = (
char*)m_page_ptr.p;
170 BOOL bWrite= WriteFile(hFile, buf, size, &dwWritten, 0);
171 if(!bWrite || dwWritten!=size)
173 request->error= GetLastError();
183 request->error = err;
186 off.QuadPart += request->par.open.page_size;
190 r= SetFilePointerEx(hFile, off, NULL, FILE_BEGIN);
193 request->error= GetLastError();
204 req->par.readWrite.pages[0].size = 0;
207 size_t bytes_read = 0;
210 bzero(&ov,
sizeof(ov));
214 ov.Offset = li.LowPart;
215 ov.OffsetHigh = li.HighPart;
218 BOOL bRead = ReadFile(hFile,
224 int err = GetLastError();
225 if (err == ERROR_HANDLE_EOF && req->action == Request::readPartial)
231 bytes_read = dwBytesRead;
233 req->par.readWrite.pages[0].size += bytes_read;
235 if(req->action == Request::readPartial)
239 DEBUG(ndbout_c(
"Read underflow %d %d\n %x\n%d %d",
240 size, offset, buf, bytes_read, return_value));
241 return ERR_ReadUnderflow;
244 if(bytes_read != size){
245 DEBUG(ndbout_c(
"Warning partial read %d != %d",
251 offset += bytes_read;
259 size_t chunk_size = 256 * 1024;
260 size_t bytes_to_write = chunk_size;
262 m_write_wo_sync +=
size;
266 bzero(&ov,
sizeof(ov));
270 ov.Offset = li.LowPart;
271 ov.OffsetHigh = li.HighPart;
273 if (size < bytes_to_write){
275 bytes_to_write =
size;
277 size_t bytes_written = 0;
280 BOOL bWrite = WriteFile(hFile, buf, bytes_to_write, &dwWritten, &ov);
282 return GetLastError();
284 bytes_written = dwWritten;
285 if (bytes_written != bytes_to_write) {
286 DEBUG(ndbout_c(
"Warning partial write %d != %d", bytes_written, bytes_to_write));
289 buf += bytes_written;
290 size -= bytes_written;
291 offset += bytes_written;
300 FsOpenReq::OM_WRITEONLY |
301 FsOpenReq::OM_READWRITE |
302 FsOpenReq::OM_APPEND )) {
306 if(!CloseHandle(hFile)) {
307 request->error = GetLastError();
309 hFile = INVALID_HANDLE_VALUE;
312 bool Win32AsyncFile::isOpen(){
313 return (hFile != INVALID_HANDLE_VALUE);
318 Win32AsyncFile::syncReq(
Request * request)
320 if(m_auto_sync_freq && m_write_wo_sync == 0){
323 if(!FlushFileBuffers(hFile)) {
324 request->error = GetLastError();
331 Win32AsyncFile::appendReq(
Request * request){
333 const char *
buf = request->par.append.buf;
334 Uint32
size = Uint32(request->par.append.size);
336 m_write_wo_sync +=
size;
340 if(!WriteFile(hFile, buf, size, &dwWritten, 0)){
341 request->error = GetLastError();
349 if(m_auto_sync_freq && m_write_wo_sync > m_auto_sync_freq){
355 Win32AsyncFile::removeReq(
Request * request)
357 if(!DeleteFile(theFileName.c_str())) {
358 request->error = GetLastError();
363 Win32AsyncFile::rmrfReq(
Request * request,
const char * src,
bool removePath){
364 if (!request->par.rmrf.directory)
367 if (!DeleteFile(src))
369 DWORD dwError = GetLastError();
370 if (dwError != ERROR_FILE_NOT_FOUND)
371 request->error = dwError;
383 hFindFile = FindFirstFile(path, &ffd);
384 if (INVALID_HANDLE_VALUE == hFindFile)
386 DWORD dwError = GetLastError();
387 if (dwError != ERROR_PATH_NOT_FOUND)
388 request->error = dwError;
391 path[strlen(path) - 1] = 0;
394 if (0 != strcmp(
".", ffd.cFileName) && 0 != strcmp(
"..", ffd.cFileName))
396 int len = strlen(path);
397 strcat(path, ffd.cFileName);
398 if(DeleteFile(path) || RemoveDirectory(path))
404 FindClose(hFindFile);
408 }
while(FindNextFile(hFindFile, &ffd));
410 FindClose(hFindFile);
411 path[strlen(path)-1] = 0;
412 if (strcmp(src, path) != 0)
414 char * t = strrchr(path,
'\\');
420 if(removePath && !RemoveDirectory(src))
421 request->error = GetLastError();
424 void Win32AsyncFile::createDirectories()
427 const char *
name = theFileName.c_str();
428 const char * base = theFileName.get_base_name();
429 while((tmp = (
char *)strstr(base, DIR_SEPARATOR)))
433 CreateDirectory(name, 0);
435 base = tmp +
sizeof(DIR_SEPARATOR);